From 27e4f6d577f3ae4d6f22e612bb286006f52132bb Mon Sep 17 00:00:00 2001 From: Krivchikov Dmitry Date: Thu, 24 Jul 2014 12:54:27 +0400 Subject: [PATCH] =?UTF-8?q?BIG=20UPDATE:=20=D0=9D=D0=BE=D0=B2=D1=8B=D0=B9?= =?UTF-8?q?=20=D0=B1=D0=B0=D0=B7=D0=BE=D0=B2=D1=8B=D0=B9=20=D0=BA=D0=BB?= =?UTF-8?q?=D0=B0=D1=81=D1=81=20=D0=BF=D0=BE=D0=B4=20=D0=BC=D0=BE=D0=B4?= =?UTF-8?q?=D0=B5=D0=BB=D0=B8,=20=D0=BD=D0=BE=D0=B2=D1=8B=D0=B5=20=D0=BC?= =?UTF-8?q?=D0=BE=D0=B4=D0=B5=D0=BB=D0=B8,=20=D0=BD=D0=BE=D0=B2=D1=8B?= =?UTF-8?q?=D0=B9=20=D0=BA=D0=BE=D0=B4=20=D0=B2=20=D0=BA=D0=BE=D0=BD=D1=82?= =?UTF-8?q?=D1=80=D0=BE=D0=BB=D0=B5=D1=80=D0=B0=D1=85=20=D0=B8=20=D0=B2?= =?UTF-8?q?=D1=8C=D1=8E=D1=85=D0=B0=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ground/app.php | 41 ++-- ground/classes/Model.php | 319 +++++++++++++++++++------ ground/controllers/IndexController.php | 5 +- ground/controllers/JsonController.php | 41 +--- ground/controllers/PageController.php | 35 ++- ground/models/Category.php | 8 +- ground/models/Point.php | 9 +- ground/models/Route.php | 12 +- ground/models/User.php | 18 +- ground/views/indexTemplate.php | 4 +- ground/views/modals/categories.php | 2 +- 11 files changed, 330 insertions(+), 164 deletions(-) diff --git a/ground/app.php b/ground/app.php index 68bbfcb..b37d5b8 100644 --- a/ground/app.php +++ b/ground/app.php @@ -29,7 +29,7 @@ class App private static $basedir = false; private static $config = array(); private static $urlParams = array(); - public static $DB = null; + private static $DB = null; public static $user = null; /** @@ -65,21 +65,7 @@ class App self::$config = $config ? include_once $config : array(); self::parseUrl(); - if (self::getConfig('DB')) - { - try - { - $confDB = self::getConfig('DB'); - self::$DB = new PDO('mysql:host=' . $confDB['host'] . ';dbname=' . $confDB['dbname'].';charset=utf8;', $confDB['user'], $confDB['password']); - - // Работать с пользователями моно только при наличии БД - self::userInit(); - } - catch (PDOException $e) - { - echo $e->getMessage(); - } - } + self::userInit(); $controller = self::$controller; $action = self::$action; @@ -93,6 +79,24 @@ class App } } + public static function DB() + { + if (self::$DB === NULL && self::getConfig('DB')) + { + try + { + $confDB = self::getConfig('DB'); + self::$DB = new PDO('mysql:host=' . $confDB['host'] . ';dbname=' . $confDB['dbname'].';charset=utf8;', $confDB['user'], $confDB['password']); + } + catch (PDOException $e) + { + echo $e->getMessage(); + } + } + + return self::$DB; + } + public static function error404($message = '') { header("HTTP/1.0 404 Not Found"); @@ -104,12 +108,11 @@ class App { if (isset($_SESSION['user_id']) && isset($_SESSION['user_key']) && $_SESSION['user_id'] && $_SESSION['user_key'] ) { - $user = new User(); - $user = $user->getByPK((int)$_SESSION['user_id']); + $user = User::model()->getByPK((int)$_SESSION['user_id']); if ( $user && md5($user->uid) == $_SESSION['user_key'] ) { - self::$user = $user; + App::$user = $user; } } } diff --git a/ground/classes/Model.php b/ground/classes/Model.php index 0258fee..69980f3 100644 --- a/ground/classes/Model.php +++ b/ground/classes/Model.php @@ -1,105 +1,233 @@ _tableName_ = 'Users'; + parent::__construct($fromArray); + } + + static function model() + { + return new self(); + } + } + + Просто новый пользователь: + new User(); + + Новый пользователь из массива данных: + new User(array('ID'=>12, 'Name'=>'John', 'Fname'=>'Doe')); + + Берём пользователя по ID: + User::model()->getByPK(2); + + Всех пользователей: + User::model()->getAll() + + Или всех пользователей с параметрами: + User::model()->getAll(array('where'=>'`ID` > 5', 'order'=>'`Name` ASC')) + + */ + +abstract class Model { + // Relations + const TO_ONE = 'TO_ONE'; + const TO_MANY = 'TO_MANY'; + private $_primaryKey_; protected $_tableName_; private $_id_; private $_vals_ = array(); + protected $_relations_ = array(); - function __construct($table) + function __construct($fromArray = array()) { - $this->_tableName_ = $table; $this->_primaryKey_ = $this->getPk(); + + if ($fromArray) + { + $this->setValues($fromArray); + } } + /** + * TODO: Проверять, есть ли такие поля в БД. + * @param type $name + * @param type $value + */ function __set($name, $value) { $this->_vals_[$name] = $value; + + if ($name == $this->_primaryKey_) + { + $this->_id_ = $value; + } } function __get($name) { - return isset($this->_vals_[$name]) ? $this->_vals_[$name] : null; - } + if (isset($this->_vals_[$name])) + { + return $this->_vals_[$name]; + } else + { + if (isset($this->_relations_[$name])) + { + extract($this->_relations_[$name]); + $model = new $targetModel; - /** - * Получаем Primary Key - * @return type - */ - private function getPk() - { - $res = App::$DB->query("SHOW KEYS FROM " . $this->_tableName_ . " WHERE Key_name = 'PRIMARY'")->fetch(PDO::FETCH_ASSOC); - return $res["Column_name"]; - } - - /** - * Возвращает объект - запись в БД. - * @param int $id - * @return \Model - */ - function getByPK($id) - { - $this->_vals_ = App::$DB->query('SELECT * FROM ' . $this->_tableName_ . ' WHERE ' . $this->_primaryKey_ . ' = ' . $id)->fetch(PDO::FETCH_ASSOC); - $this->_id_ = $this->_vals_[$this->_primaryKey_]; - return $this; - } - - static function getByPrimaryKey($id) - { - $instance = new self(); - return $instance->getByPK($id); + switch ($relationType) + { + case self::TO_ONE: + return $model::model()->getOne($targetField, $this->$localField); + break; + case self::TO_MANY: + return $model::model()->getAll(array('where' => "`$targetField` = '" . $this->$localField . "'")); + break; + default: + throw new Exception('Undefined relation type'); + break; + } + } + } + return null; } /** - * Возвращает массив с ассоциативными массивами, соответствующими записями в БД. - * @param string $where просто строка с условиями: (`id` > 1) AND (`name` == 'TEST') - * @param string $order строка с именем толбца и напрабления: `summ` DESC + * Получаем Primary Key * @return type */ - function getAll($where = '', $order = '') + private function getPk() { - /* TODO: Переделать этот метод. Сделать статическим, возвращать массив объектов. */ - $sql = 'SELECT * FROM ' . $this->_tableName_; - $sql .= $where ? ' WHERE '.$where : ''; - $sql .= $order ? ' ORDER BY '.$order : ''; + $res = App::DB()->query("SHOW KEYS FROM " . $this->_tableName_ . " WHERE Key_name = 'PRIMARY'")->fetch(PDO::FETCH_ASSOC); + return $res["Column_name"]; + } - $res = App::$DB->query($sql); + /** + * Устанавливает отношение с другой таблицей + * @param string $nameOfRelation - название отношения. В дальнейшем по этому имени будт происходить обращение. + * @param string $localField - локальные данные по которым происходит связывание. + * @param string $targetModel - имя внешней модели (с которой хотим связаться). + * @param string $targetField - имя поля в удалённой таблице. + * @param const $relationType - тип связи (к одному / ко многим). + * @return obkect/array + */ + public function setRelation($nameOfRelation, $localField, $targetModel, $targetField, $relationType) + { + return $this->_relations_[$nameOfRelation] = array( + 'localField' => $localField, + 'targetModel' => $targetModel, + 'targetField' => $targetField, + 'relationType' => $relationType, + ); + } + + /** + * Возвращает объект - запись в БД. + * @param int $id + * @return \Model + */ + function getByPK($id) + { + $this->_vals_ = App::DB()->query('SELECT * FROM ' . $this->_tableName_ . ' WHERE ' . $this->_primaryKey_ . ' = ' . $id)->fetch(PDO::FETCH_ASSOC); + $this->_id_ = $this->_vals_[$this->_primaryKey_]; + return $this; + } + + /** + * Возвращает массив с объектами, соответствующими записями в БД. + * @param array $params ['where'] просто строка с условиями: (`id` > 1) AND (`name` == 'TEST'); ['order'] строка с именем толбца и напрабления: `summ` DESC + * @return array с объектами + */ + function getAll($params = array()) + { + $sql = 'SELECT * FROM `' . $this->_tableName_ . '`'; + $sql .= isset($params['where'])&&$params['where'] ? ' WHERE ' . $params['where'] : ''; + $sql .= isset($params['order'])&&$params['order'] ? ' ORDER BY ' . $params['order'] : ''; + $sql .= isset($params['limit'])&&$params['limit'] ? ' LIMIT ' . $params['limit'] : ''; + + $res = App::DB()->query($sql); - $this->_id_ = NULL; // Это больше не конкретная запись $ready = array(); -//print_r($res);die; + + $calledClass = get_called_class(); while ($res && $row = $res->fetch(PDO::FETCH_ASSOC)) { - $ready[$row[$this->_primaryKey_]] = $row; + $ready[$row[$this->_primaryKey_]] = isset($params['asArray'])&&$params['asArray'] ? $row : new $calledClass($row); } return $ready; } - /** - * Удаляет запись из БД. - * @param int $id - * @return boolean - */ - function delete($id) + /** + * Возвращает один элемент, соотбетствующий параметрам + * @param string $whereField - имя поля по которому производим поиск + * @param type $whereValue - искомое значение + * @return type + */ + function getOne($whereField, $whereValue) { - return $id ? App::$DB->query('DELETE FROM ' . $this->_tableName_ . ' WHERE ' . $this->_primaryKey_ . ' = ' . $id) : false; + return array_shift( + $this->getAll(array( + 'where' => '`' . $whereField . '` = "' . $whereValue . '"', + 'limit' => 1 + )) + ); } - /** - * Добавляет новую запись в БД. - * @param array $values - ассоциативный массив соо значениями. - * @return int/boolean - id добавленной записи или false. - */ + /** + * Удаляет запись из БД. + * @param int $id + * @return boolean + */ + function delete($id) + { + return $id ? App::DB()->query('DELETE FROM `' . $this->_tableName_ . '` WHERE `' . $this->_primaryKey_ . '` = ' . $id) : false; + } + + /** + * Добавляет новую запись в БД. + * @param array $values - ассоциативный массив соо значениями. + * @return object - id добавленной записи или false. + */ + function add2($values) + { + $values = $this->_vals_; + unset($values[$this->_primaryKey_]); + + $q = array(); + foreach ($values as $val) + { + $q[] = '?'; + } + + var_dump('INSERT INTO `' . $this->_tableName_ . '` (`' . implode('`, `', array_keys($values)) . '`) VALUES (' . implode(', ', array_values($q)) . ') ');die; + $res = App::DB()->prepare_query('INSERT INTO `' . $this->_tableName_ . '` (`' . implode('`, `', array_keys($values)) . '`) VALUES (' . implode(', ', array_values($q)) . ') ', self::arrayWithTypes($values)); + + if ($res) + { + throw new Exception('MySQL error #' . $res->errno . ' - ' . $res->error); + } + + return $this->getByPK(App::DB()->insert_id); + } + + function add($values) { - - $request = App::$DB->prepare('INSERT INTO ' . $this->_tableName_ . ' (' . implode(',', array_keys($values)) . ') values (:' . implode(', :', array_keys($values)) . ')'); + $request = App::DB()->prepare('INSERT INTO ' . $this->_tableName_ . ' (' . implode(',', array_keys($values)) . ') values (:' . implode(', :', array_keys($values)) . ')'); if ( $request->execute((array) $values) ) { - return $this->getByPK(App::$DB->lastInsertId()); + return $this->getByPK(App::DB()->lastInsertId()); } else { @@ -108,39 +236,82 @@ class Model } /** - * Устанавливает значения полей из массива. - * @param array $values - ассоциативный массив со значениями. - */ + * Устанавливает значения полей из массива. Нужно проверять, есть ли такие поля в таблице. + * @param array $values - ассоциативный массив со значениями. + */ function setValues($values) { + if (isset($values[$this->_primaryKey_])) + { + $this->_id_ = $values[$this->_primaryKey_]; + } + $this->_vals_ = $values; } /** - * Сохраняет объект в БД. - * @return object/boolean - */ - function save() + * Сохраняет объект в БД. + * @return object/boolean + */ + function save2() + { + if (!$this->_id_ || !$this->_vals_) + { + if ($this->_vals_) + { + return $this->add($this->_vals_); + } + else + { + return FALSE; + } + } + + $values = $this->_vals_; + unset($values[$this->_primaryKey_]); + $keys = array_keys($values); + $values = array_values($values); + $values[] = $this->_id_; + $res = App::DB()->prepare_query('UPDATE `' . $this->_tableName_ . '` SET `' . implode('`=?, `', array_values($keys)) . '`=? WHERE `' . $this->_primaryKey_ . '`=?', self::arrayWithTypes($values)); + + return $res ? $this : FALSE; + } + + function save() { if (!$this->_id_ || !$this->_vals_) - return FALSE; + { + if ($this->_vals_) + { + return $this->add($this->_vals_); + } + else + { + return FALSE; + } + } $values = $this->_vals_; unset($values[$this->_primaryKey_]); - $request = App::$DB->prepare('UPDATE ' . $this->_tableName_ . ' SET ' . implode('=?, ', array_keys($values)) . '=? WHERE '.$this->_primaryKey_.'='.$this->_id_); + $request = App::DB()->prepare('UPDATE ' . $this->_tableName_ . ' SET ' . implode('=?, ', array_keys($values)) . '=? WHERE '.$this->_primaryKey_.'='.$this->_id_); $res = $request->execute(array_values($values)); return $res ? $this : FALSE; } /** - * Возвращает значения полей объекта в виде ассоциативного массива. - * @return array - */ - function getValues() - { - return $this->_vals_; - } + * Возвращает значения полей объекта в виде ассоциативного массива. + * @return array + */ + function getValues() + { + return $this->_vals_; + } + + function removeId() + { + $this->_vals_[$this->_primaryKey_] = $this->_id_ = NULL; + } } diff --git a/ground/controllers/IndexController.php b/ground/controllers/IndexController.php index 422da6f..519092e 100644 --- a/ground/controllers/IndexController.php +++ b/ground/controllers/IndexController.php @@ -47,10 +47,11 @@ class IndexController extends Controller self::addVar('isAdmin', (int)(App::$user && App::$user->isAdmin == 1) ); - $res = App::$DB->query("SELECT COUNT(`id`) pointsCount FROM `points`")->fetch(PDO::FETCH_ASSOC); + $res = App::DB()->query("SELECT COUNT(`id`) pointsCount FROM `points`")->fetch(PDO::FETCH_ASSOC); App::setConfig('title', $res['pointsCount'].' или даже больше поводов не сидеть дома'); self::addVar('pointsCount', $res['pointsCount']); + $og = array(); if(isset($_GET['point']) && $_GET['point'] && is_numeric($_GET['point'])) { $id = (int) $_GET['point']; @@ -110,7 +111,7 @@ class IndexController extends Controller $user = new User(); $user->getByUID($uLoginUser['identity']); - +//var_dump($uLoginUser,'

', $user);die; if( !$user->id ) { $user = $user->add(array( diff --git a/ground/controllers/JsonController.php b/ground/controllers/JsonController.php index af2ddd8..bbfd03c 100644 --- a/ground/controllers/JsonController.php +++ b/ground/controllers/JsonController.php @@ -9,17 +9,18 @@ class JsonController extends Controller static function actionPoints() { $points = Point::model()->getAll(); - $categories = Category::model()->getAll(); + $categories = Category::model()->getAll(array('asArray'=>true)); $result = array(); foreach ($points as $point) { - $result[$point['id']]['id'] = $point['id']; - $result[$point['id']]['name'] = $point['name']; - $result[$point['id']]['lat'] = $point['lat']; - $result[$point['id']]['lng'] = $point['lng']; - $result[$point['id']]['categoryId'] = $point['categoryId']; - $result[$point['id']]['categoryIcon'] = $categories[$point['categoryId']]['icon']; + $id = $point->id; + $result[$id]['id'] = $point->id; + $result[$id]['name'] = $point->name; + $result[$id]['lat'] = $point->lat; + $result[$id]['lng'] = $point->lng; + $result[$id]['categoryId'] = $point->categoryId; + $result[$id]['categoryIcon'] = $categories[$point->categoryId]['icon']; } self::renderPartial('json.php', array( @@ -35,34 +36,12 @@ class JsonController extends Controller $id = (int) App::getParam('id'); if ($id) { - //$point = Point::getByPrimaryKey($id); - //$point = $point->getByPK($id); - -// $point = new Point(); -// $point->name = 'TEST'; -// $point->lat = 12; -// $point->lng = 44; -// $point->img = 'sdfsdfsdf'; -// $point->description = 'sdfsdfsdfsdfsdfsdfsdfsfd'; -// $point->categoryId = 1; -// $point->source = ''; -// $point->author = 2; -// $point->date = time(); -// -// print_r($point->save()); -// -// print '



'; -// -// -// print_r($point); -// die; - $point = Point::model()->getByPK($id); $point->descriptionHtml = nl2br($point->description); $point->name = htmlspecialchars($point->name); - $categories = Category::model()->getAll(); + $categories = Category::model()->getAll(array('asArray'=>true)); $point->categoryIcon = $categories[$point->categoryId]['icon']; $point->categoryName = $categories[$point->categoryId]['name']; @@ -79,7 +58,7 @@ class JsonController extends Controller */ static function actionCategories() { - $categories = Category::model()->getAll(); + $categories = Category::model()->getAll(array('asArray'=>true)); self::renderPartial('json.php', array( 'data' => $categories, diff --git a/ground/controllers/PageController.php b/ground/controllers/PageController.php index 4ec3741..6907926 100644 --- a/ground/controllers/PageController.php +++ b/ground/controllers/PageController.php @@ -12,30 +12,25 @@ class PageController extends Controller self::addStyle('/css/bootstrap.min.css'); self::addStyle('/css/bootstrap-theme.min.css'); - $categoryId = (int)App::getParam('category'); - $where = $categoryId ? 'categoryId = '.$categoryId : ''; - - $points = new Point(); - $points = $points->getAll($where, 'id DESC'); - - $categories = new Category(); - $categories = $categories->getAll('', 'ord'); - - $users = new User(); - $users = $users->getAll(); + $param['order']='id DESC'; + $param['where']=App::getParam('category') ? 'categoryId = '.(int)App::getParam('category') : ''; + $points = Point::model()->getAll($param); + $categories = Category::model()->getAll(); $result = array(); - foreach ($points as $point) - { - $result[$point['id']]['id'] = $point['id']; - $result[$point['id']]['name'] = $point['name']; - $result[$point['id']]['img'] = $point['img']; - $result[$point['id']]['categoryIcon'] = $categories[$point['categoryId']]['icon']; - $result[$point['id']]['author'] = $users[$point['author']]['nick']; - } + foreach ($points as $point) { + $id = $point->id; + $result[$id]['id'] = $point->id; + $result[$id]['name'] = $point->name; + $result[$id]['lat'] = $point->lat; + $result[$id]['lng'] = $point->lng; + $result[$id]['author'] = $point->authorUser->name; + $result[$id]['categoryId'] = $point->categoryId; + $result[$id]['categoryIcon'] = $categories[$point->categoryId]->icon; + } - $res = App::$DB->query("SELECT COUNT(`id`) pointsCount FROM `points`")->fetch(PDO::FETCH_ASSOC); + $res = App::DB()->query("SELECT COUNT(`id`) pointsCount FROM `points`")->fetch(PDO::FETCH_ASSOC); App::setConfig('title', $res['pointsCount'] . ' или даже больше поводов не сидеть дома'); self::render('pointsTemplate.php', array( diff --git a/ground/models/Category.php b/ground/models/Category.php index c74ce13..c82a03b 100644 --- a/ground/models/Category.php +++ b/ground/models/Category.php @@ -2,14 +2,16 @@ class Category extends Model { - function __construct() + function __construct($fromArray = array()) { - return self::model(); + $this->_tableName_ = 'categories'; + parent::__construct($fromArray); + $this->setRelation('points', 'id', 'Point', 'categoryId', self::TO_MANY); } static function model() { - return new Model('categories'); + return new self(); } } diff --git a/ground/models/Point.php b/ground/models/Point.php index 712136c..01afe63 100644 --- a/ground/models/Point.php +++ b/ground/models/Point.php @@ -2,14 +2,17 @@ class Point extends Model { - function __construct() + function __construct($fromArray = array()) { - return self::model(); + $this->_tableName_ = 'points'; + parent::__construct($fromArray); + $this->setRelation('category', 'categoryId', 'Category', 'id', self::TO_ONE); + $this->setRelation('authorUser', 'author', 'User', 'id', self::TO_ONE); } static function model() { - return new Model('points'); + return new self(); } } diff --git a/ground/models/Route.php b/ground/models/Route.php index 6773397..e922f4c 100644 --- a/ground/models/Route.php +++ b/ground/models/Route.php @@ -2,16 +2,20 @@ class Route extends Model { - function __construct() + function __construct($fromArray = array()) { - $this->_tableName_ = 'routes'; - parent::__construct(); + parent::__construct($fromArray); + } + + static function model() + { + return new self(); } function getByAuthor($authorId) { - return $this->getAll('`author` = '.$authorId); + return $this->getAll(array('where'=>'`author` = '.$authorId)); } } diff --git a/ground/models/User.php b/ground/models/User.php index 25236e4..ab9119e 100644 --- a/ground/models/User.php +++ b/ground/models/User.php @@ -2,20 +2,28 @@ class User extends Model { - function __construct() + function __construct($fromArray = array()) { - $this->_tableName_ = 'users'; - parent::__construct(); + parent::__construct($fromArray); + $this->setRelation('category', 'catogoryId', 'Category', 'id', self::TO_ONE); + } + + static function model() + { + return new self(); } function getByUID($uid) { - $res = App::$DB->query('SELECT `id` FROM ' . $this->_tableName_ . ' WHERE `uid` = "' . $uid . '"'); + $res = App::DB()->query('SELECT `id` FROM `' . $this->_tableName_ . '` WHERE `uid` = "' . $uid . '"'); if ($res) { $res = $res->fetch(PDO::FETCH_ASSOC); - return parent::getByPK((int)$res['id']); + print_r($res['id']); + $user = $this->getByPK((int)$res['id']); + + return $user; } else { diff --git a/ground/views/indexTemplate.php b/ground/views/indexTemplate.php index a9fc33c..71f5ebe 100644 --- a/ground/views/indexTemplate.php +++ b/ground/views/indexTemplate.php @@ -50,7 +50,7 @@
-
+ name?>
@@ -68,7 +68,7 @@
-
×
+
× name ?>
У вас пока нет сохраненных маршрутов. diff --git a/ground/views/modals/categories.php b/ground/views/modals/categories.php index a00871f..40079a1 100644 --- a/ground/views/modals/categories.php +++ b/ground/views/modals/categories.php @@ -7,7 +7,7 @@