Welcome to svlab

Member Login

Lost your password?

Not a member yet? Sign Up!

Предыдущий пост Следующий пост
11 Dec 2019

В моей социальной сети реализованы следующие возможности:
- создание своих HTML анкет;
- обмен сообщениями, фото, аудио и видео;
- встроенный плеер облачного аудио;
- чат комнаты для общения;
- игра в симпатии.
Для этого мною был написан API экшенов:
 
var svlaboratoryBaseUrl = "http://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";
- получение списка пользователей прошедших модерацию;
 
И список действий связанных с пользователями:
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 был реализован как действия PHP фреймворка 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 и метод save

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 find($id)
    {
        $id = (int) $id;
        $select = $this->getDBTable()->select();
        //$this->_beforeFetch($select); //ERROR delete comment with Join User becouse next id must be c.id
        $select->where("id = ?", $id);
        
        $row = $this->getDBTable()->fetchRow($select);
        
        if (!$row) {
            return array();
        }
        
        return $row->toArray();
    }

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 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 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 и используя класс Zend Framework для таблиц базы данных Zend_Db_Table_Abstract.
Класс модели с реализацией основных действий с таблицами 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.
 
Личный плеер аудио загрузок и чаты были реализованы как отдельные приложения отображаемые во фреймах.
 
Посмотреть готовое приложение социальной сети можно по ссылке:
 

Социальная сеть Любовь SVLAB

Описание Социальной сети и мобильное приложение тут: 

http://svlaboratory.org/blog/blog-single/articleid/59

 

Один из возможных минимальных

Список литературы (для изучения с нуля)

Читать можно в том же порядке

1. А. Кириленко Самоучитель HTML. - Питер - 2005 - 272 с.

2. Д. Макфарланд JavaScript и jQuery - Эксмо. - 2017 - 880 с.

3. Э.А. Майер CSS Карманный справочник - Вильямс. - 2018 - 288 с.

4. Д. Флэнаган JavaScript: карманный справочник - Вильямс. - 2018 - 320 с.

5. Н.А. Прохороренок jQuery. Новый стиль программирования на JavaScript - Вильямс. - 2010 -272 с.

6. М. В. Кузнецов, И.В. Симдянов Самоучитель PHP 7. - БХВ-Петербург - 2018 - 448 с.

7. В. Васвани Zend Framework: Разработка веб-приложений на PHP - Питер, 2012 - 432 с.

8. А. Бьюли Изучаем SQL - Символ-Плюс. - 2007 - 312 с.

9. В.А. Дронов HTML, JavaScript, PHP и MySQL. Джентльменский набор Web-мастера - BHV-СПб - 2018 -


Количество просмотров: 252

SHARE:

#

Post dicussion

Контакты

Для связи svbeat@yandex.ru

  • 1
  • 1
  • 1