Как написать простую Социальную сеть

от автора


В моей социальной сети реализованы следующие возможности:
— создание своих HTML анкет;
— обмен сообщениями, фото, аудио и видео;
— встроенный плеер облачного аудио;
— чат комнаты для общения;
— игра в симпатии.

Для этого мною был написан API действий:

API приложения сервера

var svlaboratoryBaseUrl = «svlaboratory.org»;

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=";
— получение маленькой копии аватара;

var getLikeProfilesUrl = svlaboratoryBaseUrl + "/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";
— получение списка пользователей прошедших проверку модератором;

И список действий связанных с пользователями:

API приложения сервера для пользователей

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 <= count($this->_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 = " . (int) $id);         $this->_afterDelete($id);     }      public function deleteByAttrib($att, $value)     {         $select = $this->getDBTable()->select();         $where = $this->getDBTable()->getAdapter()->quoteInto("`$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 {     protected $_name = 'chat'; } 
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
— таблица пользователей и их параметров;

К примеру таблица 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
— таблица анкет и их параметров;

chat
— таблица сообщений;

-- ----------------------------------------------------- -- 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; 

file
— таблица файлов;

foto
— таблица фото;

like
— таблица плюсов;

token
— таблица ключей авторизации;

moder
— таблица проверки анкет модератором;

userorder
— таблица действий пользователя;

Такие таблицы базы данных, действия серверного приложения и приложение клиента браузера легко написать более менее опытному программисту освоившему книги по
CSS, HTML, JS, PHP, SQL.

Личный плеер аудио загрузок и чаты были реализованы как отдельные приложения отображаемые во frame теге кода HTML приложения клиента браузера.

Также социальная сеть имеет доступ к отдельным приложениям и играм моего авторства во вкладке игры. Приложение социальной сети позволяет легко добавить свои игры заполнив форму описания игры. Основным полем этой формы является URL WEB адрес публикуемого приложения или игры. В результате приложение или игра будут показаны во frame теге HTML страницы приложения социальной сети.

Посмотреть готовое приложение социальной сети можно по ссылке:
Социальная сеть Любовь SVLAB
Описание Социальной сети и мобильное приложение тут:
http://svlaboratory.org/blog/blog-single/articleid/59
или на 4PDA: Социальная сеть Любовь SVLAB

ссылка на оригинал статьи https://habr.com/ru/post/479558/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *