Init
|
|
@ -0,0 +1 @@
|
|||
ground/config.php
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
<?php
|
||||
|
||||
class App
|
||||
{
|
||||
private static $url = array();
|
||||
private static $controller = 'IndexController';
|
||||
private static $action = 'actionIndex';
|
||||
private static $basedir = false;
|
||||
private static $config = array();
|
||||
private static $urlParams = array();
|
||||
public static $DB = null;
|
||||
|
||||
/**
|
||||
* Разбивает урл на контроллер, метод и выбирает параметры.
|
||||
*/
|
||||
private static function parseUrl()
|
||||
{
|
||||
self::$url = explode('/', $_SERVER['REQUEST_URI']);
|
||||
self::$controller = isset(self::$url[1]) && self::$url[1] ? ucfirst(self::$url[1]) . 'Controller' : self::$controller;
|
||||
self::$action = isset(self::$url[2]) && self::$url[2] ? 'action' . ucfirst(self::$url[2]) : self::$action;
|
||||
|
||||
// Разбираем параметры из урла
|
||||
if ((count(self::$url) > 3) && (self::$url[3]))
|
||||
{
|
||||
for ($index = 3; $index < count(self::$url); $index = $index + 2)
|
||||
{
|
||||
$paramName = self::$url[$index];
|
||||
$paramValue = isset(self::$url[$index + 1]) && self::$url[$index + 1] ? self::$url[$index + 1] : NULL;
|
||||
self::$urlParams[$paramName] = $paramValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Загружает класс контроллера.
|
||||
* @param string $controllerName
|
||||
*/
|
||||
private static function loadController($controllerName)
|
||||
{
|
||||
include_once 'controllers/' . strtolower($controllerName) . '.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Основной метод для запуска приложения.
|
||||
* @param array $config
|
||||
*/
|
||||
public static function run($config)
|
||||
{
|
||||
ob_start();
|
||||
self::$config = is_array($config) ? $config : array();
|
||||
self::parseUrl();
|
||||
|
||||
//var_dump(self::$controller, self::$action);die;
|
||||
|
||||
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']);
|
||||
|
||||
foreach (glob(App::getBasedir() . "models/*.php") as $filename)
|
||||
{
|
||||
include_once $filename;
|
||||
}
|
||||
} catch (PDOException $e)
|
||||
{
|
||||
echo $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
$controller = self::$controller;
|
||||
$action = self::$action;
|
||||
|
||||
if (method_exists($controller, $action))
|
||||
{
|
||||
$controller::$action();
|
||||
} else
|
||||
{
|
||||
self::error404();
|
||||
}
|
||||
}
|
||||
|
||||
public static function error404()
|
||||
{
|
||||
header("HTTP/1.0 404 Not Found");
|
||||
die('404');
|
||||
}
|
||||
|
||||
public static function redirect($url)
|
||||
{
|
||||
header("Location: " . $url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает директорию фреймворка /full/path/ground/
|
||||
* @return type
|
||||
*/
|
||||
public static function getBasedir()
|
||||
{
|
||||
if (!self::$basedir)
|
||||
self::$basedir = dirname(__FILE__) . '/';
|
||||
|
||||
return self::$basedir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает значение параметра из конфига
|
||||
* @param string $paramName
|
||||
* @return multi
|
||||
*/
|
||||
public static function getConfig($paramName)
|
||||
{
|
||||
return isset(self::$config[$paramName]) ? self::$config[$paramName] : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает значение в конфиге
|
||||
* @param string $paramName
|
||||
* @param multi $paramValue
|
||||
* @return true
|
||||
*/
|
||||
public static function setConfig($paramName, $paramValue)
|
||||
{
|
||||
self::$config[$paramName] = $paramValue;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает значение параметра, переданного в URL
|
||||
* @param string $paramName
|
||||
* @return string
|
||||
*/
|
||||
public static function getParam($paramName)
|
||||
{
|
||||
return isset(self::$urlParams[$paramName]) ? self::$urlParams[$paramName] : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает массив параметров, переданных в URL
|
||||
* @return array
|
||||
*/
|
||||
public static function getParams()
|
||||
{
|
||||
return self::$urlParams;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
abstract class Controller
|
||||
{
|
||||
|
||||
static $layout = 'layout.php';
|
||||
|
||||
static function renderPartial($template, $data, $return = false)
|
||||
{
|
||||
if (!file_exists(App::getBasedir() . 'views/' . $template))
|
||||
return 'Template not found';
|
||||
|
||||
if ($return)
|
||||
$oldContentFormBuffer_temp = ob_get_clean();
|
||||
|
||||
extract($data);
|
||||
|
||||
include App::getBasedir() . 'views/' . $template;
|
||||
|
||||
if ($return)
|
||||
{
|
||||
$newContentFormBuffer_temp = ob_get_clean();
|
||||
echo $oldContentFormBuffer_temp;
|
||||
return $newContentFormBuffer_temp;
|
||||
} else
|
||||
{
|
||||
echo $newContentFormBuffer_temp;
|
||||
}
|
||||
}
|
||||
|
||||
static function render($template, $data, $return = false)
|
||||
{
|
||||
$content = self::renderPartial($template, $data, true);
|
||||
$result = self::renderPartial(self::$layout, array('content' => $content), true);
|
||||
|
||||
if ($return)
|
||||
{
|
||||
return $result;
|
||||
} else
|
||||
{
|
||||
echo $result;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
class Model
|
||||
{
|
||||
|
||||
private $_primaryKey_;
|
||||
protected $_tableName_;
|
||||
private $_id_;
|
||||
private $_vals_ = array();
|
||||
|
||||
function __construct()
|
||||
{
|
||||
$this->_primaryKey_ = $this->getPk();
|
||||
}
|
||||
|
||||
function __set($name, $value)
|
||||
{
|
||||
$this->_vals_[$name] = $value;
|
||||
}
|
||||
|
||||
function __get($name)
|
||||
{
|
||||
return isset($this->_vals_[$name]) ? $this->_vals_[$name] : null;
|
||||
}
|
||||
|
||||
function getPk()
|
||||
{
|
||||
$res = App::$DB->query("SHOW KEYS FROM " . $this->_tableName_ . " WHERE Key_name = 'PRIMARY'")->fetch(PDO::FETCH_ASSOC);
|
||||
return $res["Column_name"];
|
||||
}
|
||||
|
||||
function getByPK($id)
|
||||
{
|
||||
return App::$DB->query('SELECT * FROM ' . $this->_tableName_ . ' WHERE ' . $this->_primaryKey_ . ' = ' . $id)->fetch(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
function getAll()
|
||||
{
|
||||
$res = App::$DB->query('SELECT * FROM ' . $this->_tableName_);
|
||||
|
||||
$ready = array();
|
||||
|
||||
while ($row = $res->fetch(PDO::FETCH_ASSOC))
|
||||
{
|
||||
$ready[$row[$this->_primaryKey_]] = $row;
|
||||
}
|
||||
|
||||
return $ready;
|
||||
}
|
||||
|
||||
function delete($id)
|
||||
{
|
||||
return App::$DB->query('DELETE FROM ' . $this->_tableName_ . ' WHERE ' . $this->_primaryKey_ . ' = ' . $id);
|
||||
}
|
||||
|
||||
function add($values)
|
||||
{
|
||||
|
||||
$request = App::$DB->prepare('INSERT INTO ' . $this->_tableName_ . ' (' . implode(',', array_keys($values)) . ') values (:' . implode(', :', array_keys($values)) . ')');
|
||||
return $request->execute((array) $values);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
// Базовый синглтон
|
||||
|
||||
abstract class Singleton
|
||||
{
|
||||
|
||||
protected static $_instance;
|
||||
|
||||
private function __construct(){
|
||||
/**
|
||||
* При этом в функцию можно вписать
|
||||
* свой код инициализации. Также можно
|
||||
* использовать деструктор класса.
|
||||
* Эти функции работают по прежднему,
|
||||
* только не доступны вне класса
|
||||
*/
|
||||
}
|
||||
|
||||
private function __clone(){
|
||||
}
|
||||
/**
|
||||
* Статическая функция, которая возвращает
|
||||
* экземпляр класса или создает новый при
|
||||
* необходимости
|
||||
*
|
||||
* @return SingletonTest
|
||||
*/
|
||||
public static function getInstance() {
|
||||
if (null === self::$_instance) {
|
||||
self::$_instance = new self();
|
||||
}
|
||||
return self::$_instance;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
$config = array(
|
||||
'title' => 'Интересные выходные вместе с wikipoints.ru',
|
||||
'DB' => array(
|
||||
'host' => 'localhost',
|
||||
'user' => 'root',
|
||||
'password' => 'root',
|
||||
'dbname' => 'poi',
|
||||
),
|
||||
);
|
||||
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
class IndexController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Действие по умолчанию - вывоим каталог товаров.
|
||||
*/
|
||||
static function actionIndex()
|
||||
{
|
||||
$category = new Category();
|
||||
|
||||
self::render('indexTemplate.php', array(
|
||||
'category' => $category->getAll(),
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверка передачи переменных в шаблон
|
||||
*/
|
||||
static function actionTest()
|
||||
{
|
||||
self::render('testTemplate.php', array(
|
||||
'name' => 'Dmitry',
|
||||
'fname' => 'Krivchikov',
|
||||
'phone' => '+7-904-610-6141',
|
||||
));
|
||||
}
|
||||
|
||||
static function actionPoints()
|
||||
{
|
||||
$points = new Point();
|
||||
$points = $points->getAll();
|
||||
|
||||
$categories = new Category();
|
||||
$categories = $categories->getAll();
|
||||
|
||||
foreach ($points as &$point) {
|
||||
$point['categoryIcon'] = $categories[$point['categoryId']]['icon'];
|
||||
$point['categoryName'] = $categories[$point['categoryId']]['name'];
|
||||
}
|
||||
|
||||
self::renderPartial('json.php', array(
|
||||
'data' => $points,
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Вывод элемента каталога. ID товара берётся из параметра /index/catalog/id/1
|
||||
*/
|
||||
static function actionCatalog()
|
||||
{
|
||||
$id = (int) App::getParam('id');
|
||||
if ($id)
|
||||
{
|
||||
$goods = new Goods();
|
||||
self::render('goods.php', $goods->getByPK($id));
|
||||
} else
|
||||
{
|
||||
App::error404();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
class YandexController extends Controller
|
||||
{
|
||||
|
||||
static function actionIndex()
|
||||
{
|
||||
|
||||
$goods = new Goods();
|
||||
$category = new Category();
|
||||
|
||||
$categorySet = $category->getAll();
|
||||
$goodsSet = $goods->getAll();
|
||||
|
||||
self::renderPartial('yandexMarket.php', array(
|
||||
'categorySet' => $categorySet,
|
||||
'goodsSet' => $goodsSet,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
class Category extends Model
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
|
||||
$this->_tableName_ = 'categories';
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
class Point extends Model
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
|
||||
$this->_tableName_ = 'points';
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
Товар:<br/>
|
||||
<br/>
|
||||
Артикул: <?=$id?><br/>
|
||||
Название: <b><?=$name?></b><br/>
|
||||
Цена: <b><?=$price?></b><br/>
|
||||
Номер категории: <?=$categoryId?><br/>
|
||||
Производитель: <?=$vendorName?><br/>
|
||||
Остаток на складе: <?=$count?><br/>
|
||||
Описание: <?=$description?><br/>
|
||||
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
test:
|
||||
<ol>
|
||||
<?php foreach ($category as $val): ?>
|
||||
<li><a href="/index/catalog/id/<?=$val['id']?>"><img src="<?=$val['icon']?>" /> <?=$val['name']?></a></li>
|
||||
<?php endforeach; ?>
|
||||
</ol>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
echo json_encode($data);
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Тестовое задание для Timeweb</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Магазин радиотоваров</h1>
|
||||
<hr/>
|
||||
<a href="/">Главная</a> |
|
||||
<a href="/yandex/" target="_blank">Выгрузка в Яндекс.Маркет</a> |
|
||||
<a href="/index/yandex/" target="_blank">Yandex</a> |
|
||||
<a href="/index/test/">Контакты</a>
|
||||
<hr/>
|
||||
<?= isset($content) && !empty($content) ? $content : 'No content =(' ?>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
Проверка кирилицы и вывода значений переданных переменных:<br/>
|
||||
<?=$name?><br/>
|
||||
<?=$fname?><br/>
|
||||
<?=$phone?><br/>
|
||||
<?=App::getConfig('hello')?>
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
<!DOCTYPE yml_catalog SYSTEM "shops.dtd">
|
||||
<yml_catalog date="<?= date('Y-m-d H-i') ?>">
|
||||
<shop>
|
||||
<name>Test for Timeweb</name>
|
||||
<company>Dmitry Krivchikov</company>
|
||||
<url>http://all4dk.blogspot.com/</url>
|
||||
|
||||
<currencies>
|
||||
<currency id="RUR" rate="1" plus="0"/>
|
||||
</currencies>
|
||||
|
||||
<categories>
|
||||
|
||||
<?php foreach ($categorySet as $val): ?>
|
||||
|
||||
<category id="<?= $val['id'] ?>"><?= $val['name'] ?></category>
|
||||
|
||||
<?php endforeach; ?>
|
||||
|
||||
</categories>
|
||||
|
||||
<local_delivery_cost><?= App::getConfig('localDeliveryPrice') ?></local_delivery_cost>
|
||||
|
||||
<offers>
|
||||
|
||||
<?php foreach ($goodsSet as $val): ?>
|
||||
|
||||
<offer id="<?= $val['id'] ?>" type="<?= $val['vendorName'] ?>" available="<?= (int) $val['count'] > 0 ? 'true' : 'false' ?>">
|
||||
<url>http://yam.loc/index/catalog/id/<?= $val['id'] ?></url>
|
||||
<price><?= $val['price'] ?></price>
|
||||
<currencyId>RUR</currencyId>
|
||||
<categoryId type="Own"><?= $val['categoryId'] ?></categoryId>
|
||||
<delivery>true</delivery>
|
||||
<local_delivery_cost><?= App::getConfig('localDeliveryPrice') ?></local_delivery_cost>
|
||||
<typePrefix><?= $categorySet[$val['categoryId']]['name'] ?></typePrefix>
|
||||
<vendor><?= $val['vendorName'] ?></vendor>
|
||||
<vendorCode>---</vendorCode>
|
||||
<model><?= $val['name'] ?></model>
|
||||
<description><?= $val['description'] ?></description>
|
||||
</offer>
|
||||
|
||||
<?php endforeach; ?>
|
||||
|
||||
</offers>
|
||||
|
||||
</shop>
|
||||
</yml_catalog>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
AddDefaultCharset utf-8
|
||||
RewriteEngine On
|
||||
|
||||
RewriteBase /
|
||||
RewriteCond %{REQUEST_FILENAME} !-l
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteRule .* index.php [L,QSA]
|
||||
|
||||
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 724 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 805 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 786 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 862 B |
|
After Width: | Height: | Size: 745 B |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 677 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 976 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 583 B |
|
After Width: | Height: | Size: 839 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 803 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 720 B |
|
After Width: | Height: | Size: 837 B |
|
After Width: | Height: | Size: 718 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 908 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1023 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 677 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 979 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 931 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 958 B |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 742 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 840 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.1 KiB |