Как написать простую Социальную сеть
В моей социальной сети реализованы следующие возможности:
- создание своих HTML анкет;
- обмен сообщениями, фото, аудио и видео;
- встроенный плеер облачного аудио;
- чат комнаты для общения;
- игра в симпатии.
var addProfileUrl = svlaboratoryBaseUrl + «/admin/chatbot/addprofile»;
— добавление профиля в базу данных;
var loginProfileUrl = svlaboratoryBaseUrl + «/admin/chatbot/profilelogin»;
— авторизация пользователя;
var getFotosUrl = svlaboratoryBaseUrl + «/admin/chatbot/getfotos»;
— получение всех файлов анкеты пользователя (фото, видео, музыки);
var delFotoUrl = svlaboratoryBaseUrl + «/admin/chatbot/deletefoto»;
— удаление фото из анкеты;
var selectFotoUrl = svlaboratoryBaseUrl + «/admin/chatbot/selectfoto»;
— выбор фото для главного фото;
var searchProfilesUrl = svlaboratoryBaseUrl + «/admin/chatbot/searchprofiles»;
— поиск анкет по параметрам;
var instaProfilesUrl = svlaboratoryBaseUrl + «/admin/chatbot/instaprofiles»;
— поиск анкет по параметрам из списка всех новых фото пользователей;
var getAnketaUrl = svlaboratoryBaseUrl + «/admin/chatbot/getanketa»;
— получение данных о профиле пользователя;
var sendProfileMsgUrl = svlaboratoryBaseUrl + «/admin/chatbot/sendmsg»;
— отправка сообщения другому пользователю;
var getAllProfileMsgsUrl = svlaboratoryBaseUrl + «/admin/chatbot/getallmsgs»;
— получение списка сообщений;
var getProfilesMsgsUrl = svlaboratoryBaseUrl + «/admin/chatbot/getprofilesmsgs»;
— получение списка пользователей отправивших сообщения;
var updateProfileUrl = svlaboratoryBaseUrl + «/admin/chatbot/updateprofile»;
— обновление позиции пользователя в списке пользователей;
var visitProfilesUrl = svlaboratoryBaseUrl + «/admin/chatbot/getvisithistory»;
— получение списка пользователей, просматривавших анкету;
var getSmallavatarUrl = svlaboratoryBaseUrl + «:8080/file/chatbotmin/»;
— получение маленькой копии изображения;
var getImgUrl = svlaboratoryBaseUrl + «:8080/file/chatbotnorm/»;
— получение обычной копии изображения;
var getSmallavatarUrl2 = svlaboratoryBaseUrl + «/application/smallavatar?url /admin/chatbot/getlikeprofiles»;
— получение списка всех пользователей для игры в симпатии;
var likeProfileUrl = svlaboratoryBaseUrl + «/admin/chatbot/likeprofile»;
— осуществить плюс анкеты;
var getLikesUrl = svlaboratoryBaseUrl + «/admin/chatbot/getlikes»;
— получить список всех плюсов;
var getModerProfilesUrl = svlaboratoryBaseUrl + «/admin/chatbot/getmoderprofiles»;
— получение списка пользователей подлежащих проверки модератором;
var moderProfileUrl = svlaboratoryBaseUrl + «/admin/chatbot/moderprofile»;
— осуществление проверки модератором пользователя;
var getModerUrl = svlaboratoryBaseUrl + «/admin/chatbot/getmoder»;
— получение списка пользователей прошедших проверку модератором;
И список действий связанных с пользователями:
var getUserorder = svlaboratoryBaseUrl + «/application/getuserorder»;
var getUserfromorderlist = svlaboratoryBaseUrl + «/application/getuserfromorderlist»;
var getUsertoorderlist = svlaboratoryBaseUrl + «/application/getusertoorderlist»;
var addUserorder = svlaboratoryBaseUrl + «/application/adduserorder»;
var getUsermyorderlist = svlaboratoryBaseUrl + «/application/getusermyorderlist»;
API был реализован как действия каркаса серверных приложений Zend Framework.
Результат запроса к API были JSON строки данных:
$response = array( "success" => true, "complete" => true, "data" => $data ); echo json_encode($response);
Клиент приложения был создан как единое приложение на Bootstrap и JQuery.
Все действия API вызывались с помощью процедуры AJAX.
Приведу немного образцов кода для осуществления CRUD на примере отправки сообщений:
Например, отправка сообщений реализована как функция sendProfileMsg на стороне клиента на языке JS:
function sendProfileMsg(text) < var data = < userid: anketaUserId, msg: text >; data["token"] = token; $.post(sendProfileMsgUrl, data, function(data) < if (data.complete) < getAllProfileMsgs(); >>, "json" ); >
И обработка запроса к серверу на языке PHP с использованием каркаса Zend Framework
public function sendmsgAction() < header('Access-Control-Allow-Origin: http://svlaboratory.org:8080'); $this->_helper->layout->disableLayout(); $this->_helper->viewRenderer->setNoRender(true); $userId = $this->_getParam('userid'); $msg = $this->_getParam('msg'); $authHelper = new Ext_Controller_Action_Helper_Auth(); $token = $this->_getParam('token', null); $ip = $_SERVER['REMOTE_ADDR']; $myUserId = $authHelper->getUserId($token, $ip); $response = array( "success" => true, "complete" => true ); $modelChat = new Model_Chat(); $data = array( "message" => $msg, "user_id_from" => $myUserId, "user_id_to" => $userId, ); $modelChat->save($data); $this->notificateUser($userId, $myUserId); echo json_encode($response); >
Для сохранения данных в базу данных тут использовался класс Model
class Ext_Model < protected $_dbAdapter; /** * * @var array */ protected $_fields = array(); protected $_primaryKey = array(); /** * * @var Zend_Db_Table_Abstract */ protected $_dbTable = null; /** * * @var string */ protected $_dbTableClass = null; protected $_id=null; public function getId() < return $this->_id; > public function setId($id) < $this->_id=$id; > public function save($data) < $insertId = null; $data = $this->_beforeSave($data); // операции для сохранения записи $cleanData = array(); $pk = array(); foreach ($this->_fields as $field) < if (array_key_exists($field, $data)) < $cleanData[$field] = $data[$field]; >> foreach ($this->_primaryKey as $field => $value) < if (isset($cleanData[$value])) < $pk[$value] = $cleanData[$value]; >> if (!empty($cleanData)) < if (empty($pk)) < $insertId = $this->insert($cleanData); $data["id"] = $insertId; > else < $this->update($pk, $cleanData); > > $this->_afterSave($data); return $insertId; > public function update($id, $data) < $data = $this->_beforeUpdate($data); $where = ""; foreach ($this->_primaryKey as $key => $values) < if ($key >0 and $key _primaryKey)) < $where .= ' and '; >$where .= "`$values`" . " = " . "$id[$values]"; unset($data[$values]); > $this->getDBTable()->update($data, $where); $data=$id+$data; $this->_afterUpdate($data); > public function insert($data) < $data = $this->_beforeInsert($data); $this->getDBTable()->insert($data); $this->setId($this->getDBTable()->getAdapter()->lastInsertId()); $this->_afterInsert($data); return $this->getDBTable()->getAdapter()->lastInsertId(); > public function fetchRowManyWhere($conditions = array()) < $select = $this->getDBTable()->select(); $this->_beforeFetch($select); foreach ($conditions as $field => $value) < $select->where("`$field` = ?", $value); > $row = $this->getDBTable()->fetchRow($select); if (!$row) < return array(); >return $row->toArray(); > public function fetchAllManyWhere($conditions = array(), $limit = null, $offset = null, $order = null) < $select = $this->getDBTable()->select(); $this->_beforeFetch($select); foreach ($conditions as $field => $value) < $select->where("`$field` = ?", $value); > if ($order !== null) < $select->order($order); > if ($limit !== null || $offset !== null) < $select->limit($limit, $offset); > $rows = $this->getDBTable()->fetchAll($select); if (!$rows) < return array(); >return $rows->toArray(); > public function delete($id) < $id=$this->_beforeDelete($id); $this->getDBTable()->delete("id `$att` = ?", $value); $this->getDBTable()->delete($where); > public function getDBTable() < if (!$this->_dbTable) < if (!$this->_dbTableClass) < throw new Ext_Model_Exception('DB table class is not set'); >$this->_dbTable = new $this->_dbTableClass; > return $this->_dbTable; > public function setDBTable(Zend_Db_Table_Abstract $table) < $this->_dbTable = $table; return $this; > public function lastInsertId() < return $this->getDBTable()->getAdapter()->lastInsertId(); > protected function _beforeFetch($select) < >protected function _beforeSave($data) < return $data; >protected function _afterSave($data) < return $data; >protected function _beforeUpdate($data) < return $data; >protected function _afterUpdate($data) < return $data; >protected function _beforeInsert($data) < return $data; >protected function _afterInsert($data) < return $data; >protected function _beforeDelete($id) < return $id; >protected function _afterDelete($id) < return $id; >>
Другие методы типа delete или fetchRow, find, fetchAll
реализуются аналогично внедряя параметры в запросы MySQL.
Класс модели с реализацией основных действий с таблицами MySQL наследуется для каждой таблицы MySQL:
class Model_DbTable_Chat extends Zend_Db_Table_Abstract
class Model_Chat extends Ext_Model < protected $_dbTableClass = 'Model_DbTable_Chat'; protected $_fields = array( 'id', 'message', 'description', 'user_id_from', 'user_id_to', 'date', ); protected $_primaryKey = array('id'); protected function _beforeInsert($data) < $data['date'] = date("Y-m-d H:i:s", time()); return $data; >public function fetchAllMsg($iser_id1, $iser_id2) < $select = $this->getDBTable()->select(); $this->_beforeFetch($select); $sql = "SELECT * FROM chatbotchat WHERE (user_id_from = :userid1 AND user_id_to = :userid2) OR (user_id_from = :userid2 AND user_id_to = :userid1) Order by date ASC"; $rows = $this->getDBTable()->getAdapter()->fetchAll($sql, array("userid1" => $iser_id1, "userid2" => $iser_id2)); if (!$rows) < return array(); >return $rows; > public function fetchReadAllMsg($iser_id1, $iser_id2) < $select = $this->getDBTable()->select(); $this->_beforeFetch($select); $sql = "UPDATE chatbotchat SET is_read = 1 WHERE (user_id_from = :userid2 AND user_id_to = :userid1)"; $this->getDBTable()->getAdapter()->query($sql, array("userid1" => $iser_id1, "userid2" => $iser_id2)); > public function fetchProfilesMsg($user_id) < $select = $this->getDBTable()->select(); $this->_beforeFetch($select); $sql = "SELECT * FROM chatbotchat WHERE (user_id_from = :userid OR user_id_to = :userid) Order by date DESC"; $rows = $this->getDBTable()->getAdapter()->fetchAll($sql, array("userid" => $user_id)); if (!$rows) < return array(); >return $rows; > >
Для ввода параметров и создания форм использовался CSS каркаса Bootstrap.
Для динамического отображения приложения использовался JavaScript и JQuery.
В базе данных MySQL были созданы сущности:
user
— таблица пользователей и их параметров;
-- ----------------------------------------------------- -- Table `svlab`.`user` -- ----------------------------------------------------- CREATE TABLE IF NOT EXISTS `svlab`.`user` ( `id` INT AUTO_INCREMENT , `first_name` VARCHAR(45) DEFAULT NULL, `last_name` VARCHAR(200) DEFAULT NULL, `nickname` VARCHAR(200) DEFAULT NULL, `gender` VARCHAR(200) DEFAULT NULL, `birth_date` DATETIME DEFAULT NULL, `avatar_url` VARCHAR(200) DEFAULT NULL, `min_avatar_url` VARCHAR(200) DEFAULT NULL, `email` VARCHAR(45) NOT NULL, `password` VARCHAR(45) DEFAULT "12345", `password_recover` VARCHAR(15) DEFAULT NULL, `country` VARCHAR(200) DEFAULT NULL, `region` VARCHAR(200) DEFAULT NULL, `city` VARCHAR(200) DEFAULT NULL, `postal_code` VARCHAR(200) DEFAULT NULL, `street` VARCHAR(200) DEFAULT NULL, `house_number` VARCHAR(200) DEFAULT NULL, `add_address_info` VARCHAR(200) DEFAULT NULL, `site` VARCHAR(200) DEFAULT NULL, `about_me_info` TEXT DEFAULT NULL, `registration_date` DATETIME NOT NULL, `comment_rating` FLOAT DEFAULT 0, `comment_rating_pos` FLOAT DEFAULT 0, `comment_rating_neg` FLOAT DEFAULT 0, `white_ips` TEXT, `is_active` TINYINT(1) DEFAULT false, PRIMARY KEY (`id`) , UNIQUE INDEX `user_id_unique` (`id` ASC) , UNIQUE INDEX `user_email_unique` (`email` ASC)) ENGINE = InnoDB;
profile
— таблица анкет и их параметров;
-- ----------------------------------------------------- -- Table `svlab`.`chat` -- ----------------------------------------------------- CREATE TABLE IF NOT EXISTS `svlab`.`chat` ( `id` INT NOT NULL AUTO_INCREMENT, `message` TEXT, `user_id_from` INT NOT NULL, `user_id_to` INT NOT NULL, `date` DATETIME, `is_read` TINYINT(1) DEFAULT false, PRIMARY KEY (`id`), UNIQUE INDEX `chatbotchat_id_unique` (`id` ASC)) ENGINE=MyISAM DEFAULT CHARSET=utf8;
token
— таблица ключей авторизации;
moder
— таблица проверки анкет модератором;
userorder
— таблица действий пользователя;
Такие таблицы базы данных, действия серверного приложения и приложение клиента браузера легко написать более менее опытному программисту освоившему книги по
CSS, HTML, JS, PHP, SQL.
Личный плеер аудио загрузок и чаты были реализованы как отдельные приложения отображаемые во frame теге кода HTML приложения клиента браузера.
Также социальная сеть имеет доступ к отдельным приложениям и играм моего авторства во вкладке игры. Приложение социальной сети позволяет легко добавить свои игры заполнив форму описания игры. Основным полем этой формы является URL WEB адрес публикуемого приложения или игры. В результате приложение или игра будут показаны во frame теге HTML страницы приложения социальной сети.
Посмотреть готовое приложение социальной сети можно по ссылке: