This commit is contained in:
Alan
2026-02-14 19:34:54 +03:00
commit 5c3329238b
867 changed files with 214778 additions and 0 deletions

5
simpla/.htaccess Normal file
View File

@@ -0,0 +1,5 @@
AddType application/octet-stream csv
AuthName "CMS"
AuthType Basic
AuthUserFile C:\laragon\www\atomic_old\simpla\.passwd
require valid-user

4
simpla/.passwd Normal file
View File

@@ -0,0 +1,4 @@
admin:$apr1$5asceyrg$9bgPtSc50E9hoCmmIPk3K0:banners,products,categories,brands,features,orders,labels,users,groups,coupons,pages,blog,comments,feedbacks,import,export,backup,stats,design,settings,currency,delivery,payment,managers,license,callbacks,articles_categories,articles,marka,model
alaev:$apr1$cmbuh3df$9VJhmckpYKDz81JPTOyzh1:banners,products,categories,brands,features,orders,labels,users,groups,coupons,pages,blog,comments,feedbacks,import,export,backup,stats,design,settings,currency,delivery,payment,managers,license,callbacks,articles_categories,articles,marka,model
Grib:$apr1$sbaru2xk$OgkV5q93tqQ0aGihz6JgV.:products,categories,brands,features,orders,labels,users,groups,coupons,pages,blog,comments,feedbacks,import,export,backup,stats,design,settings,currency,delivery,payment,managers,license,callbacks,articles,articles_categories,marka,model
Olga:$apr1$c6m9xwli$AN5vPxodjhlkHf1jFUgO0/:products,categories,brands,features,pages,blog,comments,feedbacks,callbacks,articles_categories,articles,marka,model

74
simpla/ActionsAdmin.php Normal file
View File

@@ -0,0 +1,74 @@
<?php
/**
* Simpla CMS
*
* @copyright 2011 Denis Pikusov
* @link http://simplacms.ru
* @author Denis Pikusov
*
*/
require_once('api/Simpla.php');
class ActionsAdmin extends Simpla
{
public function fetch()
{
// Обработка действий
if($this->request->method('post'))
{
// Действия с выбранными
$ids = $this->request->post('check');
if(is_array($ids))
switch($this->request->post('action'))
{
case 'disable':
{
$this->actions->update_post($ids, array('visible'=>0));
break;
}
case 'enable':
{
$this->actions->update_post($ids, array('visible'=>1));
break;
}
case 'delete':
{
foreach($ids as $id)
$this->actions->delete_post($id);
break;
}
}
}
$filter = array();
$filter['page'] = max(1, $this->request->get('page', 'integer'));
$filter['limit'] = 20;
// Поиск
$keyword = $this->request->get('keyword', 'string');
if(!empty($keyword))
{
$filter['keyword'] = $keyword;
$this->design->assign('keyword', $keyword);
}
$posts_count = $this->actions->count_posts($filter);
// Показать все страницы сразу
if($this->request->get('page') == 'all')
$filter['limit'] = $posts_count;
$posts = $this->actions->get_posts($filter);
$this->design->assign('posts_count', $posts_count);
$this->design->assign('pages_count', ceil($posts_count/$filter['limit']));
$this->design->assign('current_page', $filter['page']);
$this->design->assign('posts', $posts);
return $this->design->fetch('actions.tpl');
}
}

View File

@@ -0,0 +1,91 @@
<?PHP
require_once('api/Simpla.php');
class ActionsPostAdmin extends Simpla
{
private $allowed_image_extentions = array('png', 'gif', 'jpg', 'jpeg', 'ico');
public function fetch()
{
if($this->request->method('post'))
{
$post->id = $this->request->post('id', 'integer');
$post->name = $this->request->post('name');
$post->date = date('Y-m-d', strtotime($this->request->post('date')));
$post->visible = $this->request->post('visible', 'boolean');
$post->url = $this->request->post('url', 'string');
$post->meta_title = $this->request->post('meta_title');
$post->meta_keywords = $this->request->post('meta_keywords');
$post->meta_description = $this->request->post('meta_description');
$post->annotation = $this->request->post('annotation');
$post->text = $this->request->post('body');
// Не допустить одинаковые URL разделов.
if(($a = $this->actions->get_post($post->url)) && $a->id!=$post->id)
{
$this->design->assign('message_error', 'url_exists');
}
else
{
if(empty($post->id))
{
$post->id = $this->actions->add_post($post);
$post = $this->actions->get_post($post->id);
$this->design->assign('message_success', 'added');
}
else
{
$this->actions->update_post($post->id, $post);
$post = $this->actions->get_post($post->id);
$this->design->assign('message_success', 'updated');
}
// Удаление изображения
if($this->request->post('delete_image'))
{
$this->actions->delete_image($post->id);
}
// Загрузка изображения
$image = $this->request->files('image');
if(!empty($image['name']) && in_array(strtolower(pathinfo($image['name'], PATHINFO_EXTENSION)), $this->allowed_image_extentions))
{
if ($image_name = $this->image->upload_image($image['tmp_name'], $image['name']))
{
$this->actions->delete_image($post->id);
$this->actions->update_post($post->id, array('image'=>$image_name));
$post->image = $image_name;
}
else
{
$this->design->assign('error', 'error uploading image');
}
}
$post = $this->actions->get_post(intval($post->id));
}
}
else
{
$post->id = $this->request->get('id', 'integer');
$post = $this->actions->get_post(intval($post->id));
if(!$post->id) $post->visible = 1;
}
if(empty($post->date))
$post->date = date($this->settings->date_format, time());
$this->design->assign('post', $post);
$this->db->query("SELECT * FROM __action_photo WHERE action_id='" . $post->id . "' ORDER BY position, id DESC");
$photos = $this->db->results();
foreach($photos as $ph) $ph->img = Img::get('files/post/' . $ph->img, array('width'=>120, 'height'=>120));
$this->design->assign('action_photos', $photos);
return $this->design->fetch('actions_post.tpl');
}
}

273
simpla/ArticleAdmin.php Normal file
View File

@@ -0,0 +1,273 @@
<?PHP
require_once('api/Simpla.php');
class ArticleAdmin extends Simpla
{
private $allowed_image_extentions = array('png', 'gif', 'jpg', 'jpeg', 'ico');
public function fetch()
{
$product_categories = array();
$article = new StdClass;
if($this->request->method('post'))
{
$article->id = $this->request->post('id', 'integer');
$article->name = $this->request->post('name');
$article->date = date('Y-m-d', strtotime($this->request->post('date')));
$article->visible = $this->request->post('visible', 'boolean');
$article->category_id = $this->request->post('category_id', 'integer');
$article->url = $this->request->post('url', 'string');
$article->meta_title = $this->request->post('meta_title');
$article->meta_keywords = $this->request->post('meta_keywords');
$article->meta_description = $this->request->post('meta_description');
$article->annotation = $this->request->post('annotation');
$article->text = $this->request->post('body');
// Категории товара
$article_categories = $this->request->post('categories');
if(is_array($article_categories))
{
foreach($article_categories as $c)
$pc[]->id = $c;
$article_categories = $pc;
}
// Связанные товары
if(is_array($this->request->post('related_products')))
{
foreach($this->request->post('related_products') as $p)
{
$rp[$p]->related_id = $p;
$rp[$p]->type = 'product';
}
$related_objects = $rp;
}
// Связанные статьи
if(is_array($this->request->post('related_articles')))
{
foreach($this->request->post('related_articles') as $p)
{
$rp[$p]->related_id = $p;
$rp[$p]->type = 'article';
}
$related_objects = $rp;
}
// Не допустить одинаковые URL разделов.
if(($a = $this->articles->get_article($article->url)) && $a->id!=$article->id)
{
$this->design->assign('message_error', 'url_exists');
}
else
{
if(empty($article->id))
{
$article->id = $this->articles->add_article($article);
$article = $this->articles->get_article($article->id);
$this->design->assign('message_success', 'added');
}
else
{
$this->articles->update_article($article->id, $article);
$article = $this->articles->get_article($article->id);
$this->design->assign('message_success', 'updated');
}
// Удаление изображения
if($this->request->post('delete_image'))
{
$this->articles->delete_image($article->id);
}
// Загрузка изображения
$image = $this->request->files('image');
if(!empty($image['name']) && in_array(strtolower(pathinfo($image['name'], PATHINFO_EXTENSION)), $this->allowed_image_extentions))
{
$image['name'] = $this->rus_lat($image['name']);
if ($image_name = $this->image->upload_image($image['tmp_name'], $image['name']))
{
$this->articles->delete_image($article->id);
$this->articles->update_article($article->id, array('image'=>$image_name));
$article->image =$image_name;
}
else
{
$this->design->assign('error', 'error uploading image');
}
}
}
// Связанные объекты
$query = $this->db->placehold('DELETE FROM __article_objects WHERE article_id=?', $article->id);
$this->db->query($query);
if(is_array($related_objects))
{
$pos = 0;
foreach($related_objects as $i=>$related_object)
$this->articles->add_related_object($article->id, $related_object->related_id, $related_object->type);
}
// Категории товара
$query = $this->db->placehold('DELETE FROM __articles_categories WHERE article_id=?', $article->id);
$this->db->query($query);
if(is_array($article_categories))
{
foreach($article_categories as $i=>$category)
$this->articles->add_article_category($article->id, $category->id, $i);
}
$this->db->query('DELETE FROM __article_models WHERE article_id=' . (int)$article->id);
$this->db->query('DELETE FROM __article_pages WHERE article_id=' . (int)$article->id);
$related_markas = $this->request->post('related_markas');
$related_models = $this->request->post('related_models');
$related_pages = $this->request->post('related_pages');
if($related_markas){
foreach($related_markas as $id) $this->db->query('INSERT INTO __article_models SET article_id=' . (int)$article->id . ", marka_id=".(int)$id.", model_id=0");
}
if($related_models){
foreach($related_models as $id){
$model = $this->model->get_model( (int)$id );
$this->db->query('INSERT INTO __article_models SET article_id=' . (int)$article->id . ", marka_id=".$model->marka->id.", model_id=" . $id);
}
}
if($related_pages){
foreach($related_pages as $id) $this->db->query('INSERT INTO __article_pages SET article_id=' . (int)$article->id . ", page_id=".(int)$id);
}
}
else
{
$article->id = $this->request->get('id', 'integer');
$article = $this->articles->get_article(intval($article->id));
}
if(!$article->id) $article->visible = 1;
if(empty($article->date)) $article->date = date($this->settings->date_format, time());
$this->design->assign('related_markas', $this->articles->get_related_markas($article->id) );
$this->design->assign('related_pages', $this->articles->get_related_pages($article->id) );
$related_models = $this->articles->get_related_models($article->id);
foreach($related_models as $row){
$marka = $this->marka->get_brand((int)$row->marka_id);
if($marka) $row->name = $marka->name . ' - ' . $row->name;
}
$this->design->assign('related_models', $related_models );
// Связанные объекты
$related_objects = $this->articles->get_related_objects(array('id'=>$article->id));
if(!empty($related_objects))
{
$r_products = array();
$r_articles = array();
foreach($related_objects as &$r_p)
if($r_p->type == 'product') $r_products[$r_p->object_id] = &$r_p;
elseif($r_p->type == 'article') $r_articles[$r_p->object_id] = &$r_p;
if(!empty($r_products)) {
$temp_products = $this->products->get_products(array('id'=>array_keys($r_products)));
foreach($temp_products as $temp_product)
$r_products[$temp_product->id] = $temp_product;
}
if(!empty($r_articles)) {
$temp_articles = $this->articles->get_articles(array('id'=>array_keys($r_articles)));
foreach($temp_articles as $temp_article)
$r_articles[$temp_article->id] = $temp_article;
}
$this->design->assign('related_products', $r_products);
$this->design->assign('related_articles', $r_articles);
}
// Категории товара
$article_categories = $this->articles->get_articles_categories_filter(array('article_id'=>/*mt1sk*//*$article->id*/(isset($article->id)) ? $article->id : -1/*/mt1sk*/));
$article->firstCategory = $article_categories ? reset($article_categories) : 0;
if(empty($article_categories))
{
if($category_id = $this->request->get('category_id'))
$article_categories[0]->id = $category_id;
else
$article_categories = array(1);
}
$this->design->assign('article_categories', $article_categories);
$categories = $this->articles->get_categories_tree();
$this->design->assign('categories', $categories);
$this->design->assign('article', $article);
$this->db->query("SELECT * FROM __article_photo WHERE article_id='" . $article->id . "' ORDER BY position, id DESC");
$photos = $this->db->results();
foreach($photos as $ph) $ph->img = Img::get('/files/article_photo/' . $ph->img, array('width'=>120, 'height'=>120));
$this->design->assign('article_photos', $photos);
//print_r($photos);die;
return $this->design->fetch('article.tpl');
}
function rus_lat($name){
$rus = array('','а','б','в','г','д','е','ё','Ё','ж','з','и','й','к',
'л','м','н','о','п','р','с','т','у','ф','х','ц','ч','ш','щ','ъ','ы','ь','э','ю','я');
$eng = array('','a','b','v','g','d','e','e','e','zh','z','i','j','k',
'l','m','n','o','p','r','s','t','u','f','h','c','ch','sh','shch','','y','','e','yu','ya');
$name = mb_strtolower($name,"UTF-8");
$name = str_replace(array('"',"'"),'',$name);
$name = str_replace(array(',',':',';','/','{','}','[',']'),'',$name);
$name = str_replace(array(' '),'_',$name);
$res = '';
$arr = $this->str_split_unicode($name);
foreach($arr as $key){
if($key == '_'){
$res .= '_';
continue;
}
if (!preg_match("/[а-я]/i", $key)){
$res .= $key;
continue;
}
$k = array_search($key,$rus);
if($k){
$res .= $eng[$k];
}
}
return $res;
}
function str_split_unicode($str, $l = 0) {
if ($l > 0) {
$ret = array();
$len = mb_strlen($str, "UTF-8");
for ($i = 0; $i < $len; $i += $l) {
$ret[] = mb_substr($str, $i, $l, "UTF-8");
}
return $ret;
}
return preg_split("//u", $str, -1, PREG_SPLIT_NO_EMPTY);
}
}

View File

@@ -0,0 +1,51 @@
<?PHP
require_once('api/Simpla.php');
class ArticleCategoriesAdmin extends Simpla
{
function fetch()
{
if($this->request->method('post'))
{
// Действия с выбранными
$ids = $this->request->post('check');
if(is_array($ids))
switch($this->request->post('action'))
{
case 'disable':
{
foreach($ids as $id)
$this->articles->update_category($id, array('visible'=>0));
break;
}
case 'enable':
{
foreach($ids as $id)
$this->articles->update_category($id, array('visible'=>1));
break;
}
case 'delete':
{
foreach($ids as $id)
$this->articles->delete_category($id);
break;
}
}
// Сортировка
$positions = $this->request->post('positions');
$ids = array_keys($positions);
sort($positions);
foreach($positions as $i=>$position)
$this->articles->update_category($ids[$i], array('position'=>$position));
}
$categories = $this->articles->get_categories_tree();
$this->design->assign('categories', $categories);
return $this->design->fetch('article_categories.tpl');
}
}

View File

@@ -0,0 +1,128 @@
<?php
require_once('api/Simpla.php');
//include $_SERVER['DOCUMENT_ROOT'].'/api/SimpleImage.php';
############################################
# Class Category - Edit the good gategory
############################################
class ArticleCategoryAdmin extends Simpla
{
private $allowed_image_extentions = array('png', 'gif', 'jpg', 'jpeg', 'ico');
function fetch()
{
if($this->request->method('post'))
{
$category->id = $this->request->post('id', 'integer');
$category->parent_id = $this->request->post('parent_id', 'integer');
$category->name = $this->request->post('name');
$category->visible = $this->request->post('visible', 'boolean');
$category->url = $this->request->post('url', 'string');
$category->meta_title = $this->request->post('meta_title');
$category->meta_keywords = $this->request->post('meta_keywords');
$category->meta_description = $this->request->post('meta_description');
$category->description = $this->request->post('description');
$image = $this->request->files('image');
// Не допустить одинаковые URL разделов.
if(($c = $this->articles->get_category($category->url)) && $c->id!=$category->id)
{
$this->design->assign('message_error', 'url_exists');
}
else
{
// Загрузка изображения
if(!empty($image['name']) && in_array(strtolower(pathinfo($image['name'], PATHINFO_EXTENSION)), $this->allowed_image_extentions))
{
$image['name'] = $this->rus_lat($image['name']);
if ($image_name = $this->image->upload_image($image['tmp_name'], $image['name']))
{
$this->articles->delete_category_image($category->id);
$this->articles->update_articles_category($article->id, array('image'=>$image_name));
$category->image = $image_name;
}
else
{
$this->design->assign('error', 'error uploading image');
}
}
if(empty($category->id))
{
$category->id = $this->articles->add_category($category);
$this->design->assign('message_success', 'added');
}
else
{
$this->articles->update_category($category->id, $category);
$this->design->assign('message_success', 'updated');
}
// Удаление изображения
if($this->request->post('delete_image'))
{
$this->articles->delete_category_image($category->id);
}
$category = $this->articles->get_category(intval($category->id));
}
}
else
{
$category->id = $this->request->get('id', 'integer');
$category = $this->articles->get_category($category->id);
if(!$category->id) $category->visible = 1;
}
$categories = $this->articles->get_categories_tree();
$this->design->assign('category', $category);
$this->design->assign('categories', $categories);
return $this->design->fetch('article_category.tpl');
}
function rus_lat($name){
$rus = array('','а','б','в','г','д','е','ё','Ё','ж','з','и','й','к',
'л','м','н','о','п','р','с','т','у','ф','х','ц','ч','ш','щ','ъ','ы','ь','э','ю','я');
$eng = array('','a','b','v','g','d','e','e','e','zh','z','i','j','k',
'l','m','n','o','p','r','s','t','u','f','h','c','ch','sh','shch','','y','','e','yu','ya');
$name = mb_strtolower($name,"UTF-8");
$name = str_replace(array('"',"'"),'',$name);
$name = str_replace(array(',',':',';','/','{','}','[',']'),'',$name);
$name = str_replace(array(' '),'_',$name);
$res = '';
$arr = $this->str_split_unicode($name);
foreach($arr as $key){
if($key == '_'){
$res .= '_';
continue;
}
if (!preg_match("/[а-я]/i", $key)){
$res .= $key;
continue;
}
$k = array_search($key,$rus);
if($k){
$res .= $eng[$k];
}
}
return $res;
}
function str_split_unicode($str, $l = 0) {
if ($l > 0) {
$ret = array();
$len = mb_strlen($str, "UTF-8");
for ($i = 0; $i < $len; $i += $l) {
$ret[] = mb_substr($str, $i, $l, "UTF-8");
}
return $ret;
}
return preg_split("//u", $str, -1, PREG_SPLIT_NO_EMPTY);
}
}

103
simpla/ArticlesAdmin.php Normal file
View File

@@ -0,0 +1,103 @@
<?php
/**
* Simpla CMS
*
* @copyright 2011 Denis Pikusov
* @link http://simplacms.ru
* @author Denis Pikusov
*
*/
require_once('api/Simpla.php');
class ArticlesAdmin extends Simpla
{ private $allowed_image_extentions = array('png', 'gif', 'jpg', 'jpeg', 'ico');
public function fetch()
{
$filter = array();
// Категории
$categories = $this->articles->get_categories_tree();
$this->design->assign('categories', $categories);
// Текущая категория
$category_id = $this->request->get('category_id', 'integer');
if($category_id && $category = $this->articles->get_category($category_id)) {
$filter['category_id'] = $category->children;
$this->design->assign('category', $category);
}
// Обработка действий
if($this->request->method('post'))
{
// Действия с выбранными
$ids = $this->request->post('check');
if(is_array($ids))
switch($this->request->post('action'))
{
case 'disable':
{
$this->articles->update_article($ids, array('visible'=>0));
break;
}
case 'enable':
{
$this->articles->update_article($ids, array('visible'=>1));
break;
}
case 'delete':
{
foreach($ids as $id)
$this->articles->delete_article($id);
break;
}
}
}
// Удаление изображения
if($this->request->post('delete_image'))
{
$this->articles->delete_image($post->id);
}
// Загрузка изображения
$image = $this->request->files('image');
if(!empty($image['name']) && in_array(strtolower(pathinfo($image['name'], PATHINFO_EXTENSION)), $this->allowed_image_extentions))
{
if ($image_name = $this->image->upload_image($image['tmp_name'], $image['name']))
{
$this->articles->delete_image($post->id);
$this->articles->update_articles($post->id, array('image'=>$image_name));
}
else
{
$this->design->assign('error', 'error uploading image');
}
}
$post = $this->articles->get_articles(intval($post->id));
$filter['page'] = max(1, $this->request->get('page', 'integer'));
$filter['limit'] = 20;
// Поиск
$keyword = $this->request->get('keyword', 'string');
if(!empty($keyword))
{
$filter['keyword'] = $keyword;
$this->design->assign('keyword', $keyword);
}
$articles = $this->articles->get_articles($filter);
$articles_count = $this->articles->count_articles($filter);
$this->design->assign('articles_count', $articles_count);
$this->design->assign('pages_count', ceil($articles_count/$filter['limit']));
$this->design->assign('current_page', $filter['page']);
$this->design->assign('articles', $articles);
return $this->design->fetch('articles.tpl');
}
}

140
simpla/BackupAdmin.php Normal file
View File

@@ -0,0 +1,140 @@
<?PHP
define( 'PCLZIP_TEMPORARY_DIR', 'simpla/files/backup/' );
require_once('api/Simpla.php');
require_once('simpla/pclzip/pclzip.lib.php');
class BackupAdmin extends Simpla
{
public function fetch()
{
$dir = 'simpla/files/backup/';
// Обработка действий
if($this->request->method('post'))
{
switch($this->request->post('action'))
{
case 'create':
{
$filename = $dir.'simpla_'.date("Y_m_d_G_i_s").'.zip';
##Дамп базы
$this->db->dump($dir.'simpla.sql');
chmod($dir.'simpla.sql', 0777);
### Архивируем
$zip = new PclZip($filename);
$v_list = $zip->create(array('files', $dir.'simpla.sql'), PCLZIP_OPT_REMOVE_PATH, $dir, PCLZIP_CB_PRE_ADD, "myCallBack");
if ($v_list == 0)
{
trigger_error('Не могу заархивировать '.$zip->errorInfo(true));
}
$this->design->assign('message_success', 'created');
break;
}
case 'restore':
{
$name = $this->request->post('name');
$archive = $dir.$name;
$zip = new PclZip($archive);
$this->clean_dir('files');
if (!$zip->extract(PCLZIP_OPT_PATH, '', PCLZIP_OPT_BY_PREG, "/^files\//", PCLZIP_CB_POST_EXTRACT, 'myPostExtractCallBack'))
{
trigger_error('Не могу разархивировать '.$zip->errorInfo(true));
}
elseif (!$zip->extract(PCLZIP_OPT_PATH, $dir, PCLZIP_OPT_BY_NAME, 'simpla.sql'))
{
trigger_error('Не могу разархивировать '.$zip->errorInfo(true));
}
elseif (!is_readable($dir.'simpla.sql'))
{
trigger_error('Не могу прочитать файл /temp/simpla.sql');
}
else
{
$this->db->restore($dir.'simpla.sql');
unlink($dir.'simpla.sql');
$this->design->assign('message_success', 'restored');
}
break;
}
case 'delete':
{
$names = $this->request->post('check');
foreach($names as $name)
unlink($dir.$name);
break;
}
}
}
$backup_files = glob($dir."*.zip");
$backups = array();
if(is_array($backup_files))
{
foreach($backup_files as $backup_file)
{
$backup = null;
$backup->name = basename($backup_file);
$backup->size = filesize($backup_file);
$backups[] = $backup;
}
}
$backups = array_reverse($backups);
$this->design->assign('backup_files_dir', $dir);
if(!is_writable($dir))
$this->design->assign('message_error', 'no_permission');
$this->design->assign('backups', $backups);
return $this->design->fetch('backup.tpl');
}
private function clean_dir($path)
{
$path= rtrim($path, '/').'/';
$handle = opendir($path);
for (;false !== ($file = readdir($handle));)
if($file != "." and $file != ".." )
{
$fullpath= $path.$file;
if( is_dir($fullpath) )
{
$this->clean_dir($fullpath);
rmdir($fullpath);
}
else
unlink($fullpath);
}
closedir($handle);
}
}
function myPostExtractCallBack($p_event, &$p_header)
{
// проверяем успешность распаковки
if ($p_header['status'] == 'ok')
{
// Меняем права доступа
@chmod($p_header['filename'], 0777);
}
return 1;
}
function myCallBack($p_event, &$p_header)
{
$fname = $p_header['stored_filename'];
if(preg_match('/^files\/products\/.+/i', $fname))
return 0;
return 1;
}

287
simpla/BannersAdmin.php Normal file
View File

@@ -0,0 +1,287 @@
<?PHP
require_once('api/Simpla.php');
error_reporting(7);
class BannersAdmin extends Simpla
{
private $BannerOfPage = 10; //Количество выводимых по умолчанию баннеров
private $allowed_image_extentions = array('png', 'gif', 'jpg', 'jpeg', 'ico');//Разрешенные расширения файлов для загрузки
function fetch()
{
/*******
Вывод групп баннеров
********************/
if(!$this->request->get('do') || $this->request->get('do') == 'groups')
{
if($this->request->get('action'))//Если есть действие "Добавить/изменить группу"
{
if($this->request->get('action') == 'edit' && $this->request->get('id'))//Если действие "изменить" подгружаем данные
{
$group = $this->banners->get_group((int)$this->request->get('id'));
}
if($this->request->post('session_id'))//Если получаем данные POST
{
if($this->request->post('name') && trim($this->request->post('name')) != '')
{
$group->name = $this->request->post('name');
if($this->request->get('action') == 'edit' && $this->request->get('id'))
{
$this->banners->update_group((int)$this->request->get('id'),array('name'=>$this->request->post('name')));
$this->design->assign('message_success', 'updated');
}
elseif($this->request->get('action') == 'add')
{
$this->db->query($this->db->placehold("INSERT INTO __banners_groups SET ?%", array('name'=>$this->request->post('name'))));
$this->design->assign('message_success', 'added');
}
}
else
{
$this->design->assign('message_error', 'empty_name');
}
}
$this->design->assign('group', $group);
$this->design->assign('action', $this->request->get('action'));
return $this->body = $this->design->fetch('banners.groups.add.edit.tpl');
}
if($this->request->post('session_id')) $this->post_update(); //Если отправили данные с действием "удалить"
list($groups,$groups_count) = $this->banners->get_groups();
foreach($groups as $key=>$value)
{
list($banner,$banner_count) = $this->banners->get_banners(ARRAY("BannerOfPage"=>10000,"group"=>$groups[$key]->id));
$groups[$key]->banner = $banner[0];
$groups[$key]->banner_count = $banner_count;
}
$this->design->assign('groups',$groups);
return $this->body = $this->design->fetch('banners.groups.tpl');
}
/*******
Вывод баннеров
********************/
elseif($this->request->get('do') == 'banners')
{
if($this->request->get('action')) //Добавление или редактирование баннера
{
$categories = $this->categories->get_categories_tree();
$brands = $this->brands->get_brands();
$pages = $this->pages->get_pages();
//Если была POST отправка данных формы добавления/редактирования
if($this->request->post('session_id'))
{
$banner->name = $this->request->post('name');
$banner->url = $this->request->post('url');
$banner->description = $this->request->post('description');
$banner->show_all_pages = (int)$this->request->post('show_all_pages');
$banner->visible = (int)$this->request->post('visible');
$banner->categories = implode(",",$this->request->post('categories'));
$banner->brands = implode(",",$this->request->post('brands'));
$banner->pages = implode(",",$this->request->post('pages'));
$banner->id_group = $this->request->get('group');
//Если есть ошибки
$upload_file = $this->request->files('image');
if($upload_file['name']=='' AND !$this->request->post('image_exist')) $error = 'not_image';
if(empty($banner->url) AND $banner->url=="") $error = 'empty_url';
if(empty($banner->name) AND $banner->name=="") $error = 'empty_name';
if($error)$this->design->assign('message_error', $error);
if(!$error && $this->request->get('action') == "add" && $this->add_banner($banner))//Если добавление баннера
{
//Если данные успешно добавлены и успешно загружено изображение баннера, выводим сообщение
$this->design->assign('message_success', 'added');
return $this->body = $this->design->fetch('banners.add.edit.tpl');
}elseif(!$error //Если реактирование баннера
AND $this->request->get('action') == "edit"
AND $this->request->get('id')
AND $this->banners->update_banner($this->request->get('id'),Array(
'name'=>$banner->name,
'url'=>$banner->url,
'description'=>$banner->description,
'visible'=>(int)$banner->visible,
'show_all_pages'=>$banner->show_all_pages,
'categories'=>$banner->categories,
'brands'=>$banner->brands,
'pages'=>$banner->pages
))
AND $this->upload_image($this->request->get('id'),TRUE))
{
//Если данные успешно обновлены, и успешно загружено изображение баннера, выводим сообщение
$this->design->assign('banners_group', $this->banners->get_group($this->request->get('group')));
$this->design->assign('message_success', 'updated');
return $this->body = $this->design->fetch('banners.add.edit.tpl');
}
$banner->category_selected = $this->request->post('categories');
$banner->brand_selected = $this->request->post('brands');
$banner->page_selected = $this->request->post('pages');
}elseif($this->request->get('action') == "edit" && $this->request->get('id')) // если это редактирование баннера, получаем информацию из БД
{
$banner = $this->banners->get_banner($this->request->get('id'));
$banner->image = $banner->image;
$banner->category_selected = explode(",",$banner->categories);//Создаем массив категорий
$banner->brand_selected = explode(",",$banner->brands);//Создаем массив брендов
$banner->page_selected = explode(",",$banner->pages);//Создаем массив страниц
}
if(!isset($banner->visible)) $banner->visible = 1;
$this->design->assign('banners_group', $this->banners->get_group($this->request->get('group')));
$this->design->assign('categories', $categories);
$this->design->assign('banner', $banner);
$this->design->assign('brands', $brands);
$this->design->assign('pages', $pages);
return $this->body = $this->design->fetch('banners.add.edit.tpl');
}
/*******
Вывод уже существующих баннеров
***************/
if($this->request->post('session_id')) $this->post_update(); //Если отправили данные с действием "Включить/выключить/удалить"
list($banners,$banners_count) = $this->banners->get_banners(ARRAY("BannerOfPage"=>10000,"group"=>$this->request->get('group')));
$current_page = max(1, $this->request->get('page', 'integer'));
$pages_count = (int)($banners_count/$this->BannerOfPage);
foreach($banners as $key=>$value){
$banners[$key]->categories_count = ($banners[$key]->categories !=0)?(int)mb_substr_count($banners[$key]->categories,",","UTF-8")+1:0;
$banners[$key]->brands_count = ($banners[$key]->brands != 0)?(int)mb_substr_count($banners[$key]->brands,",","UTF-8")+1:0;
$banners[$key]->pages_count = ($banners[$key]->pages!=0)?(int)mb_substr_count($banners[$key]->pages,",","UTF-8")+1:0;
}
$this->design->assign('banners_group', $this->banners->get_group($this->request->get('group')));
$this->design->assign('banners_count', $banners_count);
$this->design->assign('banners_images_dir', $this->config->banners_images_dir);
$this->design->assign('pages_count', $pages_count);
$this->design->assign('current_page', $current_page);
$this->design->assign('banners', $banners);
return $this->body = $this->design->fetch('banners.show.list.tpl');
}
}
/****
Функция добавления баннера
****/
function add_banner($banner)
{
$query = $this->db->placehold("INSERT INTO __banners SET ?%", $banner);
//exit($query);
$this->db->query($query);
return $this->upload_image($this->db->insert_id())?true:false;
}
/****
Функция загрузки изображения баннера
****/
function upload_image($idBanner,$deleteOldImageBanner = FALSE)
{
// Загрузка изображения
$image = $this->request->files('image');
$image = preg_replace("/\s+/", '_', $this->request->files('image'));
$imageFilename = "";
if(isset($image['name']) && in_array(strtolower(pathinfo($image['name'], PATHINFO_EXTENSION)), $this->allowed_image_extentions))
{
if($deleteOldImageBanner)
{
$banner = $this->banners->get_banner($idBanner);
$this->banners->delete_image($banner->image);
}
$imageFilename = $idBanner.'-'.$image['name'];
if(!move_uploaded_file($image['tmp_name'], $this->config->root_dir.$this->config->banners_images_dir.$imageFilename))
{
$this->design->assign('message_error', 'error_uploading_image');
return false;
}
$query = $this->db->placehold("UPDATE __banners SET position=id, image=? WHERE id=? LIMIT 1", $imageFilename ,$idBanner);
return $this->db->query($query)?true:false;
}
return true;
}
/****
Функция обновления баннера, а именно: показать/скрыть/удалить баннер
****/
function post_update()
{
if($this->request->get('do') == 'groups')
{
// Действия с выбранными
$ids = $this->request->post('check');
if(!empty($ids))
{
switch($this->request->post('action'))
{
case 'delete':
{
foreach($ids as $id)
$this->banners->delete_group($id);
break;
}
}
}
}
elseif($this->request->get('do') == 'banners')
{
// Сортировка
$positions = $this->request->post('positions');
$ids = array_keys($positions);
sort($positions);
foreach($positions as $i=>$position)
{
$this->banners->update_banner($ids[$i], array('position'=>$position));
}
// Действия с выбранными
$ids = $this->request->post('check');
if(!empty($ids))
{
switch($this->request->post('action'))
{
case 'disable':
{
$this->banners->update_banner($ids, array('visible'=>0));
break;
}
case 'enable':
{
$this->banners->update_banner($ids, array('visible'=>1));
break;
}
case 'delete':
{
foreach($ids as $id)
$this->banners->delete_banner($id);
break;
}
}
}
}
}
}

71
simpla/BlogAdmin.php Normal file
View File

@@ -0,0 +1,71 @@
<?php
/**
* Simpla CMS
*
* @copyright 2011 Denis Pikusov
* @link http://simplacms.ru
* @author Denis Pikusov
*
*/
require_once('api/Simpla.php');
class BlogAdmin extends Simpla
{
public function fetch()
{
// Обработка действий
if($this->request->method('post'))
{
// Действия с выбранными
$ids = $this->request->post('check');
if(is_array($ids))
switch($this->request->post('action'))
{
case 'disable':
{
$this->blog->update_post($ids, array('visible'=>0));
break;
}
case 'enable':
{
$this->blog->update_post($ids, array('visible'=>1));
break;
}
case 'delete':
{
foreach($ids as $id)
$this->blog->delete_post($id);
break;
}
}
}
$filter = array();
$filter['page'] = max(1, $this->request->get('page', 'integer'));
$filter['limit'] = 20;
// Поиск
$keyword = $this->request->get('keyword', 'string');
if(!empty($keyword))
{
$filter['keyword'] = $keyword;
$this->design->assign('keyword', $keyword);
}
$posts_count = $this->blog->count_posts($filter);
// Показать все страницы сразу
if($this->request->get('page') == 'all')
$filter['limit'] = $posts_count;
$posts = $this->blog->get_posts($filter);
$this->design->assign('posts_count', $posts_count);
$this->design->assign('pages_count', ceil($posts_count/$filter['limit']));
$this->design->assign('current_page', $filter['page']);
$this->design->assign('posts', $posts);
return $this->design->fetch('blog.tpl');
}
}

110
simpla/BrandAdmin.php Normal file
View File

@@ -0,0 +1,110 @@
<?php
require_once('api/Simpla.php');
############################################
# Class Category - Edit the good gategory
############################################
class BrandAdmin extends Simpla
{
private $allowed_image_extentions = array('png', 'gif', 'jpg', 'jpeg', 'ico');
function fetch()
{
if($this->request->method('post'))
{
$brand->id = $this->request->post('id', 'integer');
$brand->name = $this->request->post('name');
$brand->description = $this->request->post('description');
$brand->url = $this->request->post('url', 'string');
$brand->meta_title = $this->request->post('meta_title');
$brand->meta_keywords = $this->request->post('meta_keywords');
$brand->meta_description = $this->request->post('meta_description');
// Не допустить одинаковые URL разделов.
if(($c = $this->brands->get_brand($brand->url)) && $c->id!=$brand->id)
{
$this->design->assign('message_error', 'url_exists');
}
else
{
if(empty($brand->id))
{
$brand->id = $this->brands->add_brand($brand);
$this->design->assign('message_success', 'added');
}
else
{
$this->brands->update_brand($brand->id, $brand);
$this->design->assign('message_success', 'updated');
}
// Удаление изображения
if($this->request->post('delete_image'))
{
$this->brands->delete_image($brand->id);
}
// Загрузка изображения
$image = $this->request->files('image');
if(!empty($image['name']) && in_array(strtolower(pathinfo($image['name'], PATHINFO_EXTENSION)), $this->allowed_image_extentions))
{
$this->brands->delete_image($brand->id);
$image['name'] = $this->rus_lat($image['name']);
$image['name'] = $this->getUniqueFileName($this->root_dir.$this->config->brands_images_dir, $image['name']);
move_uploaded_file($image['tmp_name'], $this->root_dir.$this->config->brands_images_dir.$image['name']);
$this->brands->update_brand($brand->id, array('image'=>$image['name']));
}
$brand = $this->brands->get_brand($brand->id);
}
}
else
{
$brand->id = $this->request->get('id', 'integer');
$brand = $this->brands->get_brand($brand->id);
}
$this->design->assign('brand', $brand);
return $this->design->fetch('brand.tpl');
}
function rus_lat($name){
$rus = array('','а','б','в','г','д','е','ё','Ё','ж','з','и','й','к',
'л','м','н','о','п','р','с','т','у','ф','х','ц','ч','ш','щ','ъ','ы','ь','э','ю','я');
$eng = array('','a','b','v','g','d','e','e','e','zh','z','i','j','k',
'l','m','n','o','p','r','s','t','u','f','h','c','ch','sh','shch','','y','','e','yu','ya');
$name = mb_strtolower($name,"UTF-8");
$name = str_replace(array('"',"'"),'',$name);
$name = str_replace(array(',',':',';','/','{','}','[',']'),'',$name);
$name = str_replace(array(' '),'_',$name);
$res = '';
$arr = $this->str_split_unicode($name);
foreach($arr as $key){
if($key == '_'){
$res .= '_';
continue;
}
if (!preg_match("/[а-я]/i", $key)){
$res .= $key;
continue;
}
$k = array_search($key,$rus);
if($k){
$res .= $eng[$k];
}
}
return $res;
}
function str_split_unicode($str, $l = 0) {
if ($l > 0) {
$ret = array();
$len = mb_strlen($str, "UTF-8");
for ($i = 0; $i < $len; $i += $l) {
$ret[] = mb_substr($str, $i, $l, "UTF-8");
}
return $ret;
}
return preg_split("//u", $str, -1, PREG_SPLIT_NO_EMPTY);
}
}

35
simpla/BrandsAdmin.php Normal file
View File

@@ -0,0 +1,35 @@
<?PHP
require_once('api/Simpla.php');
class BrandsAdmin extends Simpla
{
function fetch()
{
// Обработка действий
if($this->request->method('post'))
{
// Действия с выбранными
$ids = $this->request->post('check');
if(is_array($ids))
switch($this->request->post('action'))
{
case 'delete':
{
foreach($ids as $id)
$this->brands->delete_brand($id);
break;
}
}
}
$brands = $this->brands->get_brands();
$this->design->assign('brands', $brands);
return $this->body = $this->design->fetch('brands.tpl');
}
}

56
simpla/CallbacksAdmin.php Normal file
View File

@@ -0,0 +1,56 @@
<?PHP
require_once('api/Simpla.php');
########################################
class CallbacksAdmin extends Simpla
{
function fetch()
{
// Обработка действий
if($this->request->method('post'))
{
// Действия с выбранными
$ids = $this->request->post('check');
if(!empty($ids))
switch($this->request->post('action'))
{
case 'delete':
{
foreach($ids as $id)
$this->callbacks->delete_callback($id);
break;
}
}
}
// Отображение
$filter = array();
$filter['page'] = max(1, $this->request->get('page', 'integer'));
$filter['limit'] = 40;
//$callbacks_count = $this->callbacks->count_callbacks($filter);
// Показать все страницы сразу
if($this->request->get('page') == 'all')
$filter['limit'] = $callbacks_count;
$callbacks = $this->callbacks->get_callbacks($filter, true);
$this->design->assign('pages_count', ceil($callbacks_count/$filter['limit']));
$this->design->assign('current_page', $filter['page']);
$this->design->assign('callbacks', $callbacks);
$this->design->assign('callbacks_count', $callbacks_count);
return $this->design->fetch('callbacks.tpl');
}
}
?>

View File

@@ -0,0 +1,50 @@
<?PHP
require_once('api/Simpla.php');
class CategoriesAdmin extends Simpla
{
function fetch()
{
if($this->request->method('post'))
{
// Действия с выбранными
$ids = $this->request->post('check');
if(is_array($ids))
switch($this->request->post('action'))
{
case 'disable':
{
foreach($ids as $id)
$this->categories->update_category($id, array('visible'=>0));
break;
}
case 'enable':
{
foreach($ids as $id)
$this->categories->update_category($id, array('visible'=>1));
break;
}
case 'delete':
{
$this->categories->delete_category($ids);
break;
}
}
// Сортировка
$positions = $this->request->post('positions');
$ids = array_keys($positions);
sort($positions);
foreach($positions as $i=>$position)
$this->categories->update_category($ids[$i], array('position'=>$position));
}
$categories = $this->categories->get_categories_tree();
$this->design->assign('categories', $categories);
return $this->design->fetch('categories.tpl');
}
}

134
simpla/CategoryAdmin.php Normal file
View File

@@ -0,0 +1,134 @@
<?php
require_once('api/Simpla.php');
if(!class_exists('SimpleImage')) include $_SERVER['DOCUMENT_ROOT'].'/api/SimpleImage.php';
############################################
# Class Category - Edit the good gategory
############################################
class CategoryAdmin extends Simpla
{
private $allowed_image_extentions = array('png', 'gif', 'jpg', 'jpeg', 'ico');
function fetch()
{
if($this->request->method('post'))
{
$category->id = $this->request->post('id', 'integer');
$category->parent_id = $this->request->post('parent_id', 'integer');
$category->name = $this->request->post('name');
$category->visible = $this->request->post('visible', 'boolean');
$category->ym = $this->request->post('ym', 'boolean');
$category->menu = $this->request->post('menu', 'boolean');
$category->from_subs = $this->request->post('from_subs', 'boolean');
$category->url = $this->request->post('url', 'string');
$category->meta_title = $this->request->post('meta_title');
$category->meta_keywords = $this->request->post('meta_keywords');
$category->meta_description = $this->request->post('meta_description');
$category->description = $this->request->post('description');
$category->category_h1 = $this->request->post('category_h1'); //var_dump($category);
$category->text_bottom = $this->request->post('text_bottom');
$category->anons = $this->request->post('anons');
$category->menu_name = $this->request->post('menu_name');
$category->how2show = $this->request->post('how2show');
// Не допустить одинаковые URL разделов.
if(($c = $this->categories->get_category($category->url)) && $c->id!=$category->id)
{
$this->design->assign('message_error', 'url_exists');
}
else
{
if(empty($category->id))
{
$category->id = $this->categories->add_category($category);
$this->design->assign('message_success', 'added');
}
else
{
$this->categories->update_category($category->id, $category);
$this->design->assign('message_success', 'updated');
}
// Удаление изображения
if($this->request->post('delete_image'))
{
$this->categories->delete_image($category->id);
}
// Загрузка изображения
$image = $this->request->files('image');
if(!empty($image['name']) && in_array(strtolower(pathinfo($image['name'], PATHINFO_EXTENSION)), $this->allowed_image_extentions))
{
$this->categories->delete_image($category->id);
$image['name'] = $this->rus_lat($image['name']);
$image['name'] = $this->getUniqueFileName($this->root_dir.$this->config->categories_images_dir, $image['name']);
move_uploaded_file($image['tmp_name'], $this->root_dir.$this->config->categories_images_dir.$image['name']);
$img = new SimpleImage($this->root_dir.$this->config->categories_images_dir.$image['name']);
$img->best_fit(1200, 1200)->save($this->root_dir.$this->config->categories_images_dir.$image['name']);
$this->categories->update_category($category->id, array('image'=>$image['name']));
}
$category = $this->categories->get_category(intval($category->id));
}
}
else
{
$category->id = $this->request->get('id', 'integer');
$category = $this->categories->get_category($category->id);
if(!$category->id) $category->visible = 1;
}
$categories = $this->categories->get_categories_tree();
$this->design->assign('category', $category); //var_dump($categories);
$this->design->assign('categories', $categories);
return $this->design->fetch('category.tpl');
}
function rus_lat($name){
$rus = array('','а','б','в','г','д','е','ё','Ё','ж','з','и','й','к',
'л','м','н','о','п','р','с','т','у','ф','х','ц','ч','ш','щ','ъ','ы','ь','э','ю','я');
$eng = array('','a','b','v','g','d','e','e','e','zh','z','i','j','k',
'l','m','n','o','p','r','s','t','u','f','h','c','ch','sh','shch','','y','','e','yu','ya');
$name = mb_strtolower($name,"UTF-8");
$name = str_replace(array('"',"'"),'',$name);
$name = str_replace(array(',',':',';','/','{','}','[',']'),'',$name);
$name = str_replace(array(' '),'_',$name);
$res = '';
$arr = $this->str_split_unicode($name);
foreach($arr as $key){
if($key == '_'){
$res .= '_';
continue;
}
if (!preg_match("/[а-я]/i", $key)){
$res .= $key;
continue;
}
$k = array_search($key,$rus);
if($k){
$res .= $eng[$k];
}
}
return $res;
}
function str_split_unicode($str, $l = 0) {
if ($l > 0) {
$ret = array();
$len = mb_strlen($str, "UTF-8");
for ($i = 0; $i < $len; $i += $l) {
$ret[] = mb_substr($str, $i, $l, "UTF-8");
}
return $ret;
}
return preg_split("//u", $str, -1, PREG_SPLIT_NO_EMPTY);
}
}

115
simpla/CommentsAdmin.php Normal file
View File

@@ -0,0 +1,115 @@
<?PHP
require_once('api/Simpla.php');
########################################
class CommentsAdmin extends Simpla
{
function fetch()
{
$filter = array();
$filter['page'] = max(1, $this->request->get('page', 'integer'));
$filter['limit'] = 40;
// Тип
$type = $this->request->get('type', 'string');
if($type)
{
$filter['type'] = $type;
$this->design->assign('type', $type);
}
// Поиск
$keyword = $this->request->get('keyword', 'string');
if(!empty($keyword))
{
$filter['keyword'] = $keyword;
$this->design->assign('keyword', $keyword);
}
// Обработка действий
if($this->request->method('post'))
{
// Действия с выбранными
$ids = $this->request->post('check');
if(!empty($ids) && is_array($ids))
switch($this->request->post('action'))
{
case 'approve':
{
foreach($ids as $id)
$this->comments->update_comment($id, array('approved'=>1));
break;
}
case 'delete':
{
foreach($ids as $id)
$this->comments->delete_comment($id);
break;
}
}
}
// Отображение
$comments_count = $this->comments->count_comments($filter);
// Показать все страницы сразу
if($this->request->get('page') == 'all')
$filter['limit'] = $comments_count;
$comments = $this->comments->get_comments($filter, true);
// Выбирает объекты, которые прокомментированы:
$products_ids = array();
$posts_ids = array();
$articles_ids = array();
foreach($comments as $comment)
{
if($comment->type == 'product')
$products_ids[] = $comment->object_id;
if($comment->type == 'blog')
$posts_ids[] = $comment->object_id;
if($comment->type == 'article')
$articles_ids[] = $comment->object_id;
}
$products = array();
foreach($this->products->get_products(array('id'=>$products_ids)) as $p)
$products[$p->id] = $p;
$posts = array();
foreach($this->blog->get_posts(array('id'=>$posts_ids)) as $p)
$posts[$p->id] = $p;
$articles = array();
foreach($this->articles->get_articles(array('id'=>$articles_ids)) as $p)
$articles[$p->id] = $p;
foreach($comments as &$comment)
{
if($comment->type == 'product' && isset($products[$comment->object_id]))
$comment->product = $products[$comment->object_id];
if($comment->type == 'blog' && isset($posts[$comment->object_id]))
$comment->post = $posts[$comment->object_id];
if($comment->type == 'article' && isset($articles[$comment->object_id]))
$comment->article = $articles[$comment->object_id];
}
$this->design->assign('pages_count', ceil($comments_count/$filter['limit']));
$this->design->assign('current_page', $filter['page']);
$this->design->assign('comments', $comments);
$this->design->assign('comments_count', $comments_count);
return $this->design->fetch('comments.tpl');
}
}
?>

57
simpla/CouponAdmin.php Normal file
View File

@@ -0,0 +1,57 @@
<?PHP
require_once('api/Simpla.php');
class CouponAdmin extends Simpla
{
public function fetch()
{
if($this->request->method('post'))
{
$coupon->id = $this->request->post('id', 'integer');
$coupon->code = $this->request->post('code', 'string');
if($this->request->post('expires'))
$coupon->expire = date('Y-m-d', strtotime($this->request->post('expire')));
else
$coupon->expire = null;
$coupon->value = $this->request->post('value', 'float');
$coupon->type = $this->request->post('type', 'string');
$coupon->min_order_price = $this->request->post('min_order_price', 'float');
$coupon->single = $this->request->post('single', 'float');
// Не допустить одинаковые URL разделов.
if(($a = $this->coupons->get_coupon((string)$coupon->code)) && $a->id!=$coupon->id)
{
$this->design->assign('message_error', 'code_exists');
}
else
{
if(empty($coupon->id))
{
$coupon->id = $this->coupons->add_coupon($coupon);
$coupon = $this->coupons->get_coupon($coupon->id);
$this->design->assign('message_success', 'added');
}
else
{
$this->coupons->update_coupon($coupon->id, $coupon);
$coupon = $this->coupons->get_coupon($coupon->id);
$this->design->assign('message_success', 'updated');
}
}
}
else
{
$coupon->id = $this->request->get('id', 'integer');
$coupon = $this->coupons->get_coupon($coupon->id);
}
// if(empty($coupon->id))
// $coupon->expire = date($this->settings->date_format, time());
$this->design->assign('coupon', $coupon);
return $this->design->fetch('coupon.tpl');
}
}

61
simpla/CouponsAdmin.php Normal file
View File

@@ -0,0 +1,61 @@
<?php
/**
* Simpla CMS
*
* @copyright 2012 Denis Pikusov
* @link http://simplacms.ru
* @author Denis Pikusov
*
*/
require_once('api/Simpla.php');
class CouponsAdmin extends Simpla
{
public function fetch()
{
// Обработка действий
if($this->request->method('post'))
{
// Действия с выбранными
$ids = $this->request->post('check');
if(is_array($ids) && count($ids)>0)
switch($this->request->post('action'))
{
case 'delete':
{
foreach($ids as $id)
$this->coupons->delete_coupon($id);
break;
}
}
}
$filter = array();
$filter['page'] = max(1, $this->request->get('page', 'integer'));
$filter['limit'] = 20;
// Поиск
$keyword = $this->request->get('keyword', 'string');
if(!empty($keyword))
{
$filter['keyword'] = $keyword;
$this->design->assign('keyword', $keyword);
}
$coupons_count = $this->coupons->count_coupons($filter);
$pages_count = ceil($coupons_count/$filter['limit']);
$filter['page'] = min($filter['page'], $pages_count);
$this->design->assign('coupons_count', $coupons_count);
$this->design->assign('pages_count', $pages_count);
$this->design->assign('current_page', $filter['page']);
$coupons = $this->coupons->get_coupons($filter);
$this->design->assign('coupons', $coupons);
return $this->design->fetch('coupons.tpl');
}
}

114
simpla/CurrencyAdmin.php Normal file
View File

@@ -0,0 +1,114 @@
<?PHP
require_once('api/Simpla.php');
########################################
class CurrencyAdmin extends Simpla
{
public function fetch()
{
// Обработка действий
if($this->request->method('post'))
{
foreach($this->request->post('currency') as $n=>$va)
foreach($va as $i=>$v)
$currencies[$i]->$n = $v;
$currencies_ids = array();
foreach($currencies as $currency)
{
if($currency->id)
$this->money->update_currency($currency->id, $currency);
else
$currency->id = $this->money->add_currency($currency);
$currencies_ids[] = $currency->id;
}
// Удалить непереданные валюты
$query = $this->db->placehold('DELETE FROM __currencies WHERE id NOT IN(?@)', $currencies_ids);
$this->db->query($query);
// Пересчитать курсы
$old_currency = $this->money->get_currency();
$new_currency = reset($currencies);
if($old_currency->id != $new_currency->id)
{
$coef = $new_currency->rate_from/$new_currency->rate_to;
if($this->request->post('recalculate') == 1)
{
$this->db->query("UPDATE __variants SET price=price*?", $coef);
$this->db->query("UPDATE __delivery SET price=price*?, free_from=free_from*?", $coef, $coef);
$this->db->query("UPDATE __orders SET delivery_price=delivery_price*?", $coef);
$this->db->query("UPDATE __orders SET total_price=total_price*?", $coef);
$this->db->query("UPDATE __purchases SET price=price*?", $coef);
$this->db->query("UPDATE __coupons SET value=value*? WHERE type='absolute'", $coef);
$this->db->query("UPDATE __coupons SET min_order_price=min_order_price*?", $coef);
$this->db->query("UPDATE __orders SET coupon_discount=coupon_discount*?", $coef);
}
$this->db->query("UPDATE __currencies SET rate_from=1.0*rate_from*$new_currency->rate_to/$old_currency->rate_to");
$this->db->query("UPDATE __currencies SET rate_to=1.0*rate_to*$new_currency->rate_from/$old_currency->rate_from");
$this->db->query("UPDATE __currencies SET rate_to = rate_from WHERE id=?", $new_currency->id);
$this->db->query("UPDATE __currencies SET rate_to = 1, rate_from = 1 WHERE (rate_to=0 OR rate_from=0) AND id=?", $new_currency->id);
}
// Отсортировать валюты
asort($currencies_ids);
$i = 0;
foreach($currencies_ids as $currency_id)
{
$this->money->update_currency($currencies_ids[$i], array('position'=>$currency_id));
$i++;
}
// Действия с выбранными
$action = $this->request->post('action');
$id = $this->request->post('action_id');
if(!empty($action) && !empty($id))
switch($action)
{
case 'disable':
{
$this->money->update_currency($id, array('enabled'=>0));
break;
}
case 'enable':
{
$this->money->update_currency($id, array('enabled'=>1));
break;
}
case 'show_cents':
{
$this->money->update_currency($id, array('cents'=>2));
break;
}
case 'hide_cents':
{
$this->money->update_currency($id, array('cents'=>0));
break;
}
case 'delete':
{
$this->money->delete_currency($id);
break;
}
}
}
// Отображение
$currencies = $this->money->get_currencies();
$currency = $this->money->get_currency();
$this->design->assign('currency', $currency);
$this->design->assign('currencies', $currencies);
return $this->design->fetch('currency.tpl');
}
}

View File

@@ -0,0 +1,56 @@
<?PHP
require_once('api/Simpla.php');
########################################
class DeliveriesAdmin extends Simpla
{
public function fetch()
{
// Обработка действий
if($this->request->method('post'))
{
// Действия с выбранными
$ids = $this->request->post('check');
if(is_array($ids))
switch($this->request->post('action'))
{
case 'disable':
{
$this->delivery->update_delivery($ids, array('enabled'=>0));
break;
}
case 'enable':
{
$this->delivery->update_delivery($ids, array('enabled'=>1));
break;
}
case 'delete':
{
foreach($ids as $id)
$this->delivery->delete_delivery($id);
break;
}
}
// Сортировка
$positions = $this->request->post('positions');
$ids = array_keys($positions);
sort($positions);
foreach($positions as $i=>$position)
$this->delivery->update_delivery($ids[$i], array('position'=>$position));
}
// Отображение
$deliveries = $this->delivery->get_deliveries();
$this->design->assign('deliveries', $deliveries);
return $this->design->fetch('deliveries.tpl');
}
}

58
simpla/DeliveryAdmin.php Normal file
View File

@@ -0,0 +1,58 @@
<?PHP
require_once('api/Simpla.php');
class DeliveryAdmin extends Simpla
{
public function fetch()
{
if($this->request->method('post'))
{
$delivery->id = $this->request->post('id', 'intgeger');
$delivery->enabled = $this->request->post('enabled', 'boolean');
$delivery->ems = $this->request->post('ems', 'boolean');
$delivery->name = $this->request->post('name');
$delivery->description = $this->request->post('description');
$delivery->price = $this->request->post('price');
$delivery->free_from = $this->request->post('free_from');
$delivery->separate_payment = $this->request->post('separate_payment');
if(!$delivery_payments = $this->request->post('delivery_payments'))
$delivery_payments = array();
if(empty($delivery->id))
{
$delivery->id = $this->delivery->add_delivery($delivery);
$this->design->assign('message_success', 'added');
}
else
{
$this->delivery->update_delivery($delivery->id, $delivery);
$this->design->assign('message_success', 'updated');
}
$this->delivery->update_delivery_payments($delivery->id, $delivery_payments);
}
else
{
$delivery->id = $this->request->get('id', 'integer');
if(!empty($delivery->id))
{
$delivery = $this->delivery->get_delivery($delivery->id);
}
$delivery_payments = $this->delivery->get_delivery_payments($delivery->id);
}
$this->design->assign('delivery_payments', $delivery_payments);
// Связанные способы оплаты
$payment_methods = $this->payment->get_payment_methods();
$this->design->assign('payment_methods', $payment_methods);
$this->design->assign('delivery', $delivery);
return $this->design->fetch('delivery.tpl');
}
}

17
simpla/ExportAdmin.php Normal file
View File

@@ -0,0 +1,17 @@
<?PHP
require_once('api/Simpla.php');
class ExportAdmin extends Simpla
{
private $export_files_dir = 'simpla/files/export/';
public function fetch()
{
$this->design->assign('export_files_dir', $this->export_files_dir);
if(!is_writable($this->export_files_dir))
$this->design->assign('message_error', 'no_permission');
return $this->design->fetch('export.tpl');
}
}

View File

@@ -0,0 +1,21 @@
<?PHP
require_once('api/Simpla.php');
class ExportUsersAdmin extends Simpla
{
private $export_files_dir = 'simpla/files/export_users/';
public function fetch()
{
$this->design->assign('export_files_dir', $this->export_files_dir);
$this->design->assign('sort', $this->request->get('sort'));
$this->design->assign('keyword', $this->request->get('keyword'));
$this->design->assign('group_id', $this->request->get('group_id'));
$this->design->assign('export_files_dir', $this->export_files_dir);
if(!is_writable($this->export_files_dir))
$this->design->assign('message_error', 'no_permission');
return $this->design->fetch('export_users.tpl');
}
}

63
simpla/FeatureAdmin.php Normal file
View File

@@ -0,0 +1,63 @@
<?PHP
require_once('api/Simpla.php');
class FeatureAdmin extends Simpla
{
function fetch()
{
if($this->request->method('post'))
{
$feature->id = $this->request->post('id', 'integer');
$feature->name = $this->request->post('name');
$feature->in_filter = intval($this->request->post('in_filter'));
$feature_categories = $this->request->post('feature_categories');
$feature->on_prod = $this->request->post('on_prod', 'boolean');
$feature->on_main = $this->request->post('on_main', 'boolean');
$feature->multiselect = $this->request->post('multiselect', 'boolean');
$feature->in_variant = $this->request->post('in_variant', 'boolean');
$feature->in_compare = $this->request->post('in_compare', 'boolean');
$feature->isrange = $this->request->post('isrange', 'boolean');
$feature->slider = $this->request->post('slider', 'boolean');
$feature->unit = $this->request->post('unit');
$feature->istext = $this->request->post('istext', 'boolean');
$feature->nameselect = $this->request->post('nameselect');
if(empty($feature->id))
{
$feature->id = $this->features->add_feature($feature);
$feature = $this->features->get_feature($feature->id);
$this->design->assign('message_success', 'added');
}
else
{
$this->features->update_feature($feature->id, $feature);
$feature = $this->features->get_feature($feature->id);
$this->design->assign('message_success', 'updated');
}
$this->features->update_feature_categories($feature->id, $feature_categories);
}
else
{
$feature->id = $this->request->get('id', 'integer');
$feature = $this->features->get_feature($feature->id);
}
$feature_categories = array();
if($feature)
{
$feature_categories = $this->features->get_feature_categories($feature->id);
}
$categories = $this->categories->get_categories_tree();
$this->design->assign('categories', $categories);
$this->design->assign('feature', $feature);
$this->design->assign('feature_categories', $feature_categories);
return $this->body = $this->design->fetch('feature.tpl');
}
}

80
simpla/FeaturesAdmin.php Normal file
View File

@@ -0,0 +1,80 @@
<?PHP
require_once('api/Simpla.php');
############################################
# Class Properties displays a list of product parameters
############################################
class FeaturesAdmin extends Simpla
{
function fetch()
{
if($this->request->method('post'))
{
// Действия с выбранными
$ids = $this->request->post('check');
if(is_array($ids))
switch($this->request->post('action'))
{
case 'set_in_filter':
{
$this->features->update_feature($ids, array('in_filter'=>1));
break;
}
case 'unset_in_filter':
{
$this->features->update_feature($ids, array('in_filter'=>0));
break;
}
case 'delete':
{
$current_cat = $this->request->get('category_id', 'integer');
foreach($ids as $id)
{
// текущие категории
$cats = $this->features->get_feature_categories($id);
// В каких категориях оставлять
$diff = array_diff($cats, (array)$current_cat);
if(!empty($current_cat) && !empty($diff))
{
$this->features->update_feature_categories($id, $diff);
}
else
{
$this->features->delete_feature($id);
}
}
break;
}
}
// Сортировка
$positions = $this->request->post('positions');
$ids = array_keys($positions);
sort($positions);
foreach($positions as $i=>$position)
$this->features->update_feature($ids[$i], array('position'=>$position));
}
$categories = $this->categories->get_categories_tree();
$category = null;
$filter = array();
$category_id = $this->request->get('category_id', 'integer');
if($category_id)
{
$category = $this->categories->get_category($category_id);
$filter['category_id'] = $category->id;
}
$features = $this->features->get_features($filter);
$this->design->assign('categories', $categories);
$this->design->assign('category', $category);
$this->design->assign('features', $features);
return $this->body = $this->design->fetch('features.tpl');
}
}

71
simpla/FeedbacksAdmin.php Normal file
View File

@@ -0,0 +1,71 @@
<?PHP
require_once('api/Simpla.php');
########################################
class FeedbacksAdmin extends Simpla
{
function fetch()
{
// Поиск
$keyword = $this->request->get('keyword', 'string');
if(!empty($keyword))
{
$filter['keyword'] = $keyword;
$this->design->assign('keyword', $keyword);
}
// Обработка действий
if($this->request->method('post'))
{
// Действия с выбранными
$ids = $this->request->post('check');
if(!empty($ids))
switch($this->request->post('action'))
{
case 'delete':
{
foreach($ids as $id)
$this->feedbacks->delete_feedback($id);
break;
}
}
}
// Отображение
$filter = array();
$filter['page'] = max(1, $this->request->get('page', 'integer'));
$filter['limit'] = 40;
// Поиск
$keyword = $this->request->get('keyword', 'string');
if(!empty($keyword))
{
$filter['keyword'] = $keyword;
$this->design->assign('keyword', $keyword);
}
$feedbacks_count = $this->feedbacks->count_feedbacks($filter);
// Показать все страницы сразу
if($this->request->get('page') == 'all')
$filter['limit'] = $feedbacks_count;
$feedbacks = $this->feedbacks->get_feedbacks($filter, true);
$this->design->assign('pages_count', ceil($feedbacks_count/$filter['limit']));
$this->design->assign('current_page', $filter['page']);
$this->design->assign('feedbacks', $feedbacks);
$this->design->assign('feedbacks_count', $feedbacks_count);
return $this->design->fetch('feedbacks.tpl');
}
}
?>

43
simpla/GroupAdmin.php Normal file
View File

@@ -0,0 +1,43 @@
<?PHP
require_once('api/Simpla.php');
class GroupAdmin extends Simpla
{
public function fetch()
{
if($this->request->method('post'))
{
$group->id = $this->request->post('id', 'integer');
$group->name = $this->request->post('name');
$group->discount = $this->request->post('discount');
if(empty($group->id))
{
$group->id = $this->users->add_group($group);
$this->design->assign('message_success', 'added');
}
else
{
$group->id = $this->users->update_group($group->id, $group);
$this->design->assign('message_success', 'updated');
}
$group = $this->users->get_group(intval($group->id));
}
else
{
$id = $this->request->get('id', 'integer');
if(!empty($id))
$group = $this->users->get_group(intval($id));
}
if(!empty($group))
{
$this->design->assign('group', $group);
}
return $this->design->fetch('group.tpl');
}
}

33
simpla/GroupsAdmin.php Normal file
View File

@@ -0,0 +1,33 @@
<?PHP
require_once('api/Simpla.php');
############################################
# Class Properties displays a list of product parameters
############################################
class GroupsAdmin extends Simpla
{
function fetch()
{
if($this->request->method('post'))
{
// Действия с выбранными
$ids = $this->request->post('check');
if(is_array($ids))
switch($this->request->post('action'))
{
case 'delete':
{
foreach($ids as $id)
$this->users->delete_group($id);
break;
}
}
}
$groups = $this->users->get_groups();
$this->design->assign('groups', $groups);
return $this->body = $this->design->fetch('groups.tpl');
}
}

94
simpla/ImagesAdmin.php Normal file
View File

@@ -0,0 +1,94 @@
<?PHP
require_once('api/Simpla.php');
class ImagesAdmin extends Simpla
{
public function fetch()
{
$images_dir = 'design/'.$this->settings->theme.'/images/';
$allowed_extentions = array('png', 'gif', 'jpg', 'jpeg', 'ico');
$images = array();
// Сохраняем
if($this->request->method('post') && !is_file($images_dir.'../locked'))
{
$old_names = $this->request->post('old_name');
$new_names = $this->request->post('new_name');
if(is_array($old_names))
foreach($old_names as $i=>$old_name)
{
$new_name = $new_names[$i];
$new_name = trim(pathinfo($new_name, PATHINFO_FILENAME).'.'.pathinfo($old_name, PATHINFO_EXTENSION), '.');
if(is_writable($images_dir) && is_file($images_dir.$old_name) && !is_file($images_dir.$new_name))
rename($images_dir.$old_name, $images_dir.$new_name);
elseif(is_file($images_dir.$new_name) && $new_name!=$old_name)
$message_error = 'name_exists';
}
$delete_image = trim($this->request->post('delete_image'), '.');
if(!empty($delete_image))
{
@unlink($images_dir.$delete_image);
}
// Загрузка изображений
if($images = $this->request->files('upload_images'))
{
for($i=0; $i<count($images['name']); $i++)
{
$name = trim($images['name'][$i], '.');
if(in_array(strtolower(pathinfo($name, PATHINFO_EXTENSION)), $allowed_extentions))
move_uploaded_file($images['tmp_name'][$i], $images_dir.$name);
}
}
if(!isset($message_error))
{
header("Location: ".$_SERVER['REQUEST_URI']);
exit();
}
else
$this->design->assign('message_error', $message_error);
}
// Чтаем все файлы
if($handle = opendir($images_dir)) {
while(false !== ($file = readdir($handle)))
{
if(is_file($images_dir.$file) && $file[0] != '.' && in_array(pathinfo($file, PATHINFO_EXTENSION), $allowed_extentions))
{
$image = null;
$image->name = $file;
$image->size = filesize($images_dir.$file);
list($image->width, $image->height) = @getimagesize($images_dir.$file);
$images[$file] = $image;
}
}
closedir($handle);
ksort($images);
}
// Если нет прав на запись - передаем в дизайн предупреждение
if(!is_writable($images_dir))
{
$this->design->assign('message_error', 'permissions');
}
elseif(is_file($images_dir.'../locked'))
{
$this->design->assign('message_error', 'theme_locked');
}
$this->design->assign('theme', $this->settings->theme);
$this->design->assign('images', $images);
$this->design->assign('images_dir', $images_dir);
return $this->design->fetch('images.tpl');
}
}

110
simpla/ImportAdmin.php Normal file
View File

@@ -0,0 +1,110 @@
<?PHP
require_once('api/Simpla.php');
class ImportAdmin extends Simpla
{
public $import_files_dir = 'simpla/files/import/';
public $import_file = 'import.csv';
public $allowed_extensions = array('csv', 'txt');
private $locale = 'ru_RU.UTF-8';
public function fetch()
{
$this->design->assign('import_files_dir', $this->import_files_dir);
if(!is_writable($this->import_files_dir))
$this->design->assign('message_error', 'no_permission');
// Проверяем локаль
$old_locale = setlocale(LC_ALL, 0);
setlocale(LC_ALL, $this->locale);
if(setlocale(LC_ALL, 0) != $this->locale)
{
$this->design->assign('message_error', 'locale_error');
$this->design->assign('locale', $this->locale);
}
setlocale(LC_ALL, $old_locale);
if($this->request->method('post') && ($this->request->files("file")))
{
$uploaded_name = $this->request->files("file", "tmp_name");
$temp = tempnam($this->import_files_dir, 'temp_');
if(!move_uploaded_file($uploaded_name, $temp))
$this->design->assign('message_error', 'upload_error');
if(!$this->convert_file($temp, $this->import_files_dir.$this->import_file))
$this->design->assign('message_error', 'convert_error');
else
$this->design->assign('filename', $this->request->files("file", "name"));
unlink($temp);
}
return $this->design->fetch('import.tpl');
}
private function convert_file($source, $dest)
{
// Узнаем какая кодировка у файла
$teststring = file_get_contents($source, null, null, null, 1000000);
if (preg_match('//u', $teststring)) // Кодировка - UTF8
{
// Просто копируем файл
return copy($source, $dest);
}
else
{
// Конвертируем в UFT8
if(!$src = fopen($source, "r"))
return false;
if(!$dst = fopen($dest, "w"))
return false;
while (($line = fgets($src, 4096)) !== false)
{
$line = $this->win_to_utf($line);
fwrite($dst, $line);
}
fclose($src);
fclose($dst);
return true;
}
}
private function win_to_utf($text)
{
if(function_exists('iconv'))
{
return @iconv('windows-1251', 'UTF-8', $text);
}
else
{
$t = '';
for($i=0, $m=strlen($text); $i<$m; $i++)
{
$c=ord($text[$i]);
if ($c<=127) {$t.=chr($c); continue; }
if ($c>=192 && $c<=207) {$t.=chr(208).chr($c-48); continue; }
if ($c>=208 && $c<=239) {$t.=chr(208).chr($c-48); continue; }
if ($c>=240 && $c<=255) {$t.=chr(209).chr($c-112); continue; }
// if ($c==184) { $t.=chr(209).chr(209); continue; };
// if ($c==168) { $t.=chr(208).chr(129); continue; };
if ($c==184) { $t.=chr(209).chr(145); continue; };
if ($c==168) { $t.=chr(208).chr(129); continue; };
if ($c==179) { $t.=chr(209).chr(150); continue; }; #і
if ($c==178) { $t.=chr(208).chr(134); continue; }; #І
if ($c==191) { $t.=chr(209).chr(151); continue; };
if ($c==175) { $t.=chr(208).chr(135); continue; };
if ($c==186) { $t.=chr(209).chr(148); continue; };
if ($c==170) { $t.=chr(208).chr(132); continue; };
if ($c==180) { $t.=chr(210).chr(145); continue; };
if ($c==165) { $t.=chr(210).chr(144); continue; };
if ($c==184) { $t.=chr(209).chr(145); continue; };
}
return $t;
}
}
}

179
simpla/IndexAdmin.php Normal file
View File

@@ -0,0 +1,179 @@
<?PHP
require_once('api/Simpla.php');
// Этот класс выбирает модуль в зависимости от параметра Section и выводит его на экран
class IndexAdmin extends Simpla
{
// Соответсвие модулей и названий соответствующих прав
private $modules_permissions = array(
'ProductsAdmin' => 'products',
'ProductAdmin' => 'products',
'CategoriesAdmin' => 'categories',
'CategoryAdmin' => 'categories',
'BrandsAdmin' => 'brands',
'BrandAdmin' => 'brands',
'FeaturesAdmin' => 'features',
'FeatureAdmin' => 'features',
'OrdersAdmin' => 'orders',
'PreordersAdmin' => 'orders',
'OrderAdmin' => 'orders',
'PreorderAdmin' => 'orders',
'OrdersLabelsAdmin' => 'labels',
'OrdersLabelAdmin' => 'labels',
'UsersAdmin' => 'users',
'UserAdmin' => 'users',
'ExportUsersAdmin' => 'users',
'GroupsAdmin' => 'groups',
'GroupAdmin' => 'groups',
'CouponsAdmin' => 'coupons',
'CouponAdmin' => 'coupons',
'PagesAdmin' => 'pages',
'PageAdmin' => 'pages',
'BlogAdmin' => 'blog',
'PostAdmin' => 'blog',
'ActionsAdmin' => 'actions',
'ActionsPostAdmin' => 'actions',
'CommentsAdmin' => 'comments',
'FeedbacksAdmin' => 'feedbacks',
'ImportAdmin' => 'import',
'ExportAdmin' => 'export',
'BackupAdmin' => 'backup',
'StatsAdmin' => 'stats',
'ThemeAdmin' => 'design',
'StylesAdmin' => 'design',
'TemplatesAdmin' => 'design',
'ImagesAdmin' => 'design',
'SettingsAdmin' => 'settings',
'CurrencyAdmin' => 'currency',
'DeliveriesAdmin' => 'delivery',
'DeliveryAdmin' => 'delivery',
'PaymentMethodAdmin' => 'payment',
'PaymentMethodsAdmin' => 'payment',
'ManagersAdmin' => 'managers',
'ManagerAdmin' => 'managers',
'ArticlesAdmin' => 'articles',
'ArticleAdmin' => 'articles',
'ArticleCategoriesAdmin' => 'article_categories',
'ArticleCategoryAdmin' => 'article_categories',
'ArticlesCategoriesAdmin' => 'articles_categories',
'ArticlesCategoryAdmin' => 'articles_categories',
'LicenseAdmin' => 'license',
'CallbacksAdmin' => 'callbacks',
'MailingMethodsAdmin' => 'maillist',
'BannersAdmin' => 'banners',
'MarkasAdmin' => 'marka',
'MarkaAdmin' => 'marka',
'ModelsAdmin' => 'model',
'ModelAdmin' => 'model',
'ServicesMenuAdmin' => 'pages',
'ServicesAdmin' => 'pages',
'ServiceAdmin' => 'pages',
);
// Конструктор
public function __construct()
{
// Вызываем конструктор базового класса
parent::__construct();
$p=11; $g=2; $x=7; $r = ''; $s = $x;
$bs = explode(' ', $this->config->license);
foreach($bs as $bl){
for($i=0, $m=''; $i<strlen($bl)&&isset($bl[$i+1]); $i+=2){
$a = base_convert($bl[$i], 36, 10)-($i/2+$s)%26;
$b = base_convert($bl[$i+1], 36, 10)-($i/2+$s)%25;
$m .= ($b * (pow($a,$p-$x-1) )) % $p;}
$m = base_convert($m, 10, 16); $s+=$x;
for ($a=0; $a<strlen($m); $a+=2) $r .= @chr(hexdec($m{$a}.$m{($a+1)}));}
@list($l->domains, $l->expiration, $l->comment) = explode('#', $r, 3);
$l->domains = explode(',', $l->domains);
$h = getenv("HTTP_HOST");
if(substr($h, 0, 4) == 'www.') $h = substr($h, 4);
else
{
$l->valid = true;
$this->design->assign('license', $l);
}
$this->design->assign('license', $l);
$this->design->set_templates_dir('simpla/design/html');
$this->design->set_compiled_dir('simpla/design/compiled');
$this->design->assign('settings', $this->settings);
$this->design->assign('config', $this->config);
// Администратор
$this->manager = $this->managers->get_manager();
$this->design->assign('manager', $this->manager);
// Берем название модуля из get-запроса
$module = $this->request->get('module', 'string');
$module = preg_replace("/[^A-Za-z0-9]+/", "", $module);
// Если не запросили модуль - используем модуль первый из разрешенных
if(empty($module) || !is_file('simpla/'.$module.'.php'))
{
foreach($this->modules_permissions as $m=>$p)
{
if($this->managers->access($p))
{
$module = $m;
break;
}
}
}
if(empty($module))
$module = 'ProductsAdmin';
// Подключаем файл с необходимым модулем
require_once('simpla/'.$module.'.php');
// Создаем соответствующий модуль
if(class_exists($module))
$this->module = new $module();
else
die("Error creating $module class");
}
function fetch()
{
$currency = $this->money->get_currency();
$this->design->assign("currency", $currency);
// Проверка прав доступа к модулю
if(isset($this->modules_permissions[get_class($this->module)])
&& $this->managers->access($this->modules_permissions[get_class($this->module)]))
{
$content = $this->module->fetch();
$this->design->assign("content", $content);
}
else
{
$this->design->assign("content", "Permission denied");
}
// Счетчики для верхнего меню
$new_orders_counter = $this->orders->count_orders(array('status'=>0));
$this->design->assign("new_orders_counter", $new_orders_counter);
$new_comments_counter = $this->comments->count_comments(array('approved'=>0));
$this->design->assign("new_comments_counter", $new_comments_counter);
// Создаем текущую обертку сайта (обычно index.tpl)
$wrapper = $this->design->smarty->getTemplateVars('wrapper');
if(is_null($wrapper))
$wrapper = 'index.tpl';
if(!empty($wrapper))
return $this->body = $this->design->fetch($wrapper);
else
return $this->body = $content;
}
}

44
simpla/LicenseAdmin.php Normal file
View File

@@ -0,0 +1,44 @@
<?PHP
require_once('api/Simpla.php');
class LicenseAdmin extends Simpla
{
public function fetch()
{
if($this->request->method('POST'))
{
$license = $this->request->post('license');
$this->config->license = trim($license);
}
$p=11; $g=2; $x=7; $r = ''; $s = $x;
$bs = explode(' ', $this->config->license);
foreach($bs as $bl){
for($i=0, $m=''; $i<strlen($bl)&&isset($bl[$i+1]); $i+=2){
$a = base_convert($bl[$i], 36, 10)-($i/2+$s)%26;
$b = base_convert($bl[$i+1], 36, 10)-($i/2+$s)%25;
$m .= ($b * (pow($a,$p-$x-1) )) % $p;}
$m = base_convert($m, 10, 16); $s+=$x;
for ($a=0; $a<strlen($m); $a+=2) $r .= @chr(hexdec($m{$a}.$m{($a+1)}));}
@list($l->domains, $l->true, $l->comment) = explode('#', $r, 3);
$l->domains = explode(',', $l->domains);
$h = getenv("HTTP_HOST");
if(substr($h, 0, 4) == 'www.') $h = substr($h, 4);
$l->valid = true;
if(!in_array($h, $l->domains))
$l->valid = true;
if(strtotime($l->true)<time() && $l->true!='*')
$l->valid = true;
$this->design->assign('license', $l);
return $this->design->fetch('license.tpl');
}
}

View File

@@ -0,0 +1,52 @@
<?php
require_once('api/Simpla.php');
class MailingMethodsAdmin extends Simpla
{
public function fetch()
{
// Одиночное удаление
if($this->request->method('get') && $this->request->get('remove'))
{
if(is_numeric($this->request->get('remove')) && $this->request->get('remove')>0)
{
$query = $this->db->placehold('delete from __mailing where id=?', $this->request->get('remove'));
$this->db->query($query);
}
}
// Множественное удаление
if($this->request->method('post') && $this->request->post('remove'))
{
print_r($this->request->post('remove'));
}
// Список адресатов
$query = $this->db->placehold('select * from __mailing');
$this->db->query($query);
$mails = array();
foreach($this->db->results() as $tmp){$mails[$tmp->id] = $tmp->email;}
// Обработчик рассылки
if($this->request->method('post') && $this->request->post('letter'))
{
$mail_header = (trim($this->request->post('header'))==''?$this->config->site_name:$this->request->post('header'));
$mail_headers = 'MIME-Version: 1.0' . "\r\n";
$mail_headers .= 'Content-type: text/html; charset=utf-8' . "\r\n";
$mail_headers .= 'From: '.iconv("utf-8","windows-1251",$this->settings->site_name).' <'.$this->settings->notify_from_email.'>' . "\r\n";
ignore_user_abort(true);
foreach($mails as $mail)
{
$hash = md5($this->settings->license.$mail);
$unsubscribe = '<p style="text-align:center; margin-top:100px; background-color:#343434; color:#cccccc;">Чтобы отписаться от рассылки, перейдите по <a style="color:#ffffff;" href="'.$this->config->root_url.'/user/?page=mailing_settings&unsubscribe='.$hash.'&mail='.$mail.'" target="_blank">ссылке</a>.</p>';
mail($mail, $mail_header, $this->request->post('letter').$unsubscribe, $mail_headers);
usleep(rand(1000000,2000000));
}
exit();
}
$this->design->assign('mailing_email', $mails);
return $this->design->fetch('mailing_methods.tpl');
}
}
?>

68
simpla/ManagerAdmin.php Normal file
View File

@@ -0,0 +1,68 @@
<?PHP
require_once('api/Simpla.php');
class ManagerAdmin extends Simpla
{
public function fetch()
{
if($this->request->method('post'))
{
$manager = new stdClass();
$manager->old_login = $this->request->post('old_login');
$manager->login = $this->request->post('login');
if(!is_writable($this->managers->passwd_file))
{
$this->design->assign('message_error', 'not_writable');
}
elseif(empty($manager->login))
{
$this->design->assign('message_error', 'empty_login');
}
elseif($this->managers->get_manager($manager->login) && $manager->login!=$manager->old_login)
{
$manager->login = $manager->old_login;
$manager->permissions = (array)$this->request->post('permissions');
$this->design->assign('message_error', 'login_exists');
}
else
{
if($this->request->post('password') != "")
$manager->password = $this->request->post('password');
// Обновляем права только другим менеджерам
$current_manager = $this->managers->get_manager();
if($manager->old_login != $current_manager->login)
$manager->permissions = (array)$this->request->post('permissions');
if(empty($manager->old_login))
{
$manager->login = $this->managers->add_manager($manager);
$this->design->assign('message_success', 'added');
}
else
{
$manager->login = $this->managers->update_manager($manager->old_login, $manager);
$this->design->assign('message_success', 'updated');
}
$manager = $this->managers->get_manager($manager->login);
}
}
else
{
$login = $this->request->get('login');
if(!empty($login))
$manager = $this->managers->get_manager($login);
}
if(!empty($manager))
{
$this->design->assign('m', $manager);
}
return $this->design->fetch('manager.tpl');
}
}

40
simpla/ManagersAdmin.php Normal file
View File

@@ -0,0 +1,40 @@
<?PHP
require_once('api/Simpla.php');
############################################
# Class Properties displays a list of product parameters
############################################
class ManagersAdmin extends Simpla
{
function fetch()
{
if($this->request->method('post'))
{
// Действия с выбранными
$logins = $this->request->post('check');
if(is_array($logins))
switch($this->request->post('action'))
{
case 'delete':
{
foreach($logins as $login)
$this->managers->delete_manager($login);
break;
}
}
}
if(!is_writable($this->managers->passwd_file))
{
$this->design->assign('message_error', 'not_writable');
}
$managers = $this->managers->get_managers();
$managers_count = $this->managers->count_managers();
$this->design->assign('managers', $managers);
$this->design->assign('managers_count', $managers_count);
return $this->body = $this->design->fetch('managers.tpl');
}
}

111
simpla/MarkaAdmin.php Normal file
View File

@@ -0,0 +1,111 @@
<?php
require_once('api/Simpla.php');
############################################
# Class Category - Edit the good gategory
############################################
class MarkaAdmin extends Simpla
{
private $allowed_image_extentions = array('png', 'gif', 'jpg', 'jpeg', 'ico');
function fetch()
{
if($this->request->method('post'))
{
$brand->id = $this->request->post('id', 'integer');
$brand->name = $this->request->post('name');
$brand->description = $this->request->post('description');
$brand->url = $this->request->post('url', 'string');
$brand->meta_title = $this->request->post('meta_title');
$brand->meta_keywords = $this->request->post('meta_keywords');
$brand->meta_description = $this->request->post('meta_description');
// Не допустить одинаковые URL разделов.
if(($c = $this->marka->get_brand($brand->url)) && $c->id!=$brand->id)
{
$this->design->assign('message_error', 'url_exists');
}
else
{
if(empty($brand->id))
{
$brand->id = $this->marka->add_brand($brand);
$this->design->assign('message_success', 'added');
}
else
{
$this->marka->update_brand($brand->id, $brand);
$this->design->assign('message_success', 'updated');
}
// Удаление изображения
if($this->request->post('delete_image'))
{
$this->marka->delete_image($brand->id);
}
// Загрузка изображения
$image = $this->request->files('image');
if(!empty($image['name']) && in_array(strtolower(pathinfo($image['name'], PATHINFO_EXTENSION)), $this->allowed_image_extentions))
{
$this->marka->delete_image($brand->id);
$image['name'] = $this->rus_lat($image['name']);
$image['name'] = $this->getUniqueFileName($this->root_dir.$this->config->marka_images_dir, $image['name']);
move_uploaded_file($image['tmp_name'], $this->root_dir.$this->config->marka_images_dir.$image['name']);
$this->marka->update_brand($brand->id, array('image'=>$image['name']));
}
$brand = $this->marka->get_brand($brand->id);
}
}
else
{
$brand->id = $this->request->get('id', 'integer');
$brand = $this->marka->get_brand($brand->id);
}
$this->design->assign('brand', $brand);
return $this->design->fetch('marka.tpl');
}
function rus_lat($name){
$rus = array('','а','б','в','г','д','е','ё','Ё','ж','з','и','й','к',
'л','м','н','о','п','р','с','т','у','ф','х','ц','ч','ш','щ','ъ','ы','ь','э','ю','я');
$eng = array('','a','b','v','g','d','e','e','e','zh','z','i','j','k',
'l','m','n','o','p','r','s','t','u','f','h','c','ch','sh','shch','','y','','e','yu','ya');
$name = mb_strtolower($name,"UTF-8");
$name = str_replace(array('"',"'"),'',$name);
$name = str_replace(array(',',':',';','/','{','}','[',']'),'',$name);
$name = str_replace(array(' '),'_',$name);
$res = '';
$arr = $this->str_split_unicode($name);
foreach($arr as $key){
if($key == '_'){
$res .= '_';
continue;
}
if (!preg_match("/[а-я]/i", $key)){
$res .= $key;
continue;
}
$k = array_search($key,$rus);
if($k){
$res .= $eng[$k];
}
}
return $res;
}
function str_split_unicode($str, $l = 0) {
if ($l > 0) {
$ret = array();
$len = mb_strlen($str, "UTF-8");
for ($i = 0; $i < $len; $i += $l) {
$ret[] = mb_substr($str, $i, $l, "UTF-8");
}
return $ret;
}
return preg_split("//u", $str, -1, PREG_SPLIT_NO_EMPTY);
}
}

37
simpla/MarkasAdmin.php Normal file
View File

@@ -0,0 +1,37 @@
<?PHP
require_once('api/Simpla.php');
class MarkasAdmin extends Simpla
{
function fetch()
{
// Обработка действий
if($this->request->method('post'))
{
// Действия с выбранными
$ids = $this->request->post('check');
if(is_array($ids))
switch($this->request->post('action'))
{
case 'delete':
{
foreach($ids as $id)
$this->marka->delete_brand($id);
break;
}
}
}
$brands = $this->marka->get_brands();
foreach($brands as $brand) $brand->models = $this->marka->getModels($brand);
$this->design->assign('brands', $brands);
return $this->body = $this->design->fetch('markas.tpl');
}
}

120
simpla/ModelAdmin.php Normal file
View File

@@ -0,0 +1,120 @@
<?php
require_once('api/Simpla.php');
############################################
# Class Category - Edit the good gategory
############################################
class ModelAdmin extends Simpla
{
private $allowed_image_extentions = array('png', 'gif', 'jpg', 'jpeg', 'ico');
function fetch()
{
if($this->request->method('post'))
{
$brand->id = $this->request->post('id', 'integer');
$brand->name = $this->request->post('name');
$brand->description = $this->request->post('description');
$brand->url = $this->request->post('url', 'string');
$brand->meta_title = $this->request->post('meta_title');
$brand->meta_keywords = $this->request->post('meta_keywords');
$brand->meta_description = $this->request->post('meta_description');
$brand->marka_id = $this->request->post('marka_id');
// Не допустить одинаковые URL разделов.
if(($c = $this->model->get_model($brand->url)) && $c->id!=$brand->id)
{
$this->design->assign('message_error', 'url_exists');
}
else
{
if(empty($brand->id))
{
$brand->id = $this->model->add_model($brand);
$this->design->assign('message_success', 'added');
}
else
{
$this->model->update_model($brand->id, $brand);
$this->design->assign('message_success', 'updated');
}
// Удаление изображения
if($this->request->post('delete_image'))
{
$this->model->delete_image($brand->id);
}
// Загрузка изображения
$image = $this->request->files('image');
if(!empty($image['name']) && in_array(strtolower(pathinfo($image['name'], PATHINFO_EXTENSION)), $this->allowed_image_extentions))
{
$this->model->delete_image($brand->id);
$image['name'] = $this->rus_lat($image['name']);
$image['name'] = $this->getUniqueFileName($this->root_dir.$this->config->model_images_dir, $image['name']);
move_uploaded_file($image['tmp_name'], $this->root_dir.$this->config->model_images_dir.$image['name']);
$this->model->update_model($brand->id, array('image'=>$image['name']));
}
$brand = $this->model->get_model($brand->id);
}
}
else
{
$brand->id = $this->request->get('id', 'integer');
$brand = $this->model->get_model($brand->id);
}
if(!$brand) $brand = new stdClass;
if($this->request->get('marka_id', 'integer') && empty($brand->id)) $brand->marka_id = $this->request->get('marka_id', 'integer');
//print_r($brand);die;
$markas = $this->marka->get_brands();
$this->design->assign('markas', $markas);
$this->design->assign('brand', $brand);
return $this->design->fetch('model.tpl');
}
function rus_lat($name){
$rus = array('','а','б','в','г','д','е','ё','Ё','ж','з','и','й','к',
'л','м','н','о','п','р','с','т','у','ф','х','ц','ч','ш','щ','ъ','ы','ь','э','ю','я');
$eng = array('','a','b','v','g','d','e','e','e','zh','z','i','j','k',
'l','m','n','o','p','r','s','t','u','f','h','c','ch','sh','shch','','y','','e','yu','ya');
$name = mb_strtolower($name,"UTF-8");
$name = str_replace(array('"',"'"),'',$name);
$name = str_replace(array(',',':',';','/','{','}','[',']'),'',$name);
$name = str_replace(array(' '),'_',$name);
$res = '';
$arr = $this->str_split_unicode($name);
foreach($arr as $key){
if($key == '_'){
$res .= '_';
continue;
}
if (!preg_match("/[а-я]/i", $key)){
$res .= $key;
continue;
}
$k = array_search($key,$rus);
if($k){
$res .= $eng[$k];
}
}
return $res;
}
function str_split_unicode($str, $l = 0) {
if ($l > 0) {
$ret = array();
$len = mb_strlen($str, "UTF-8");
for ($i = 0; $i < $len; $i += $l) {
$ret[] = mb_substr($str, $i, $l, "UTF-8");
}
return $ret;
}
return preg_split("//u", $str, -1, PREG_SPLIT_NO_EMPTY);
}
}

37
simpla/ModelsAdmin.php Normal file
View File

@@ -0,0 +1,37 @@
<?PHP
require_once('api/Simpla.php');
class ModelsAdmin extends Simpla
{
function fetch()
{
// Обработка действий
if($this->request->method('post'))
{
// Действия с выбранными
$ids = $this->request->post('check');
if(is_array($ids))
switch($this->request->post('action'))
{
case 'delete':
{
foreach($ids as $id)
$this->model->delete_model($id);
break;
}
}
}
$brands = $this->model->get_models();
foreach($brands as $model) $model->marka = $this->model->getMarka($model);
$this->design->assign('brands', $brands);
return $this->body = $this->design->fetch('models.tpl');
}
}

254
simpla/OrderAdmin.php Normal file
View File

@@ -0,0 +1,254 @@
<?PHP
require_once('api/Simpla.php');
############################################
# Class Product - edit the static section
############################################
class OrderAdmin extends Simpla
{
public function fetch()
{
if($this->request->method('post'))
{
$order->id = $this->request->post('id', 'integer');
$order->name = $this->request->post('name');
$order->email = $this->request->post('email');
$order->phone = $this->request->post('phone');
$order->address = $this->request->post('address');
$order->comment = $this->request->post('comment');
$order->note = $this->request->post('note');
$order->discount = $this->request->post('discount', 'floatr');
$order->coupon_discount = $this->request->post('coupon_discount', 'floatr');
$order->delivery_id = $this->request->post('delivery_id', 'integer');
$order->delivery_price = $this->request->post('delivery_price', 'float');
$order->payment_method_id = $this->request->post('payment_method_id', 'integer');
$order->paid = $this->request->post('paid', 'integer');
$order->user_id = $this->request->post('user_id', 'integer');
$order->separate_delivery = $this->request->post('separate_delivery', 'integer');
if(!$order_labels = $this->request->post('order_labels'))
$order_labels = array();
if(empty($order->id))
{
$order->id = $this->orders->add_order($order);
$this->design->assign('message_success', 'added');
}
else
{
$this->orders->update_order($order->id, $order);
$this->design->assign('message_success', 'updated');
}
$this->orders->update_order_labels($order->id, $order_labels);
if($order->id)
{
// Покупки
$purchases = array();
if($this->request->post('purchases'))
{
foreach($this->request->post('purchases') as $n=>$va) foreach($va as $i=>$v)
$purchases[$i]->$n = $v;
}
$posted_purchases_ids = array();
foreach($purchases as $purchase)
{
$variant = $this->variants->get_variant($purchase->variant_id);
if(!empty($purchase->id))
if(!empty($variant))
$this->orders->update_purchase($purchase->id, array('variant_id'=>$purchase->variant_id, 'variant_name'=>$variant->name, 'price'=>$purchase->price, 'amount'=>$purchase->amount));
else
$this->orders->update_purchase($purchase->id, array('price'=>$purchase->price, 'amount'=>$purchase->amount));
else
$purchase->id = $this->orders->add_purchase(array('order_id'=>$order->id, 'variant_id'=>$purchase->variant_id, 'variant_name'=>$variant->name, 'price'=>$purchase->price, 'amount'=>$purchase->amount));
$posted_purchases_ids[] = $purchase->id;
}
// Удалить непереданные товары
foreach($this->orders->get_purchases(array('order_id'=>$order->id)) as $p)
if(!in_array($p->id, $posted_purchases_ids))
$this->orders->delete_purchase($p->id);
// Принять?
if($this->request->post('status_new'))
$new_status = 0;
elseif($this->request->post('status_accept'))
$new_status = 1;
elseif($this->request->post('status_done'))
$new_status = 2;
elseif($this->request->post('status_deleted'))
$new_status = 3;
else
$new_status = $this->request->post('status', 'string');
if($new_status == 0)
{
if(!$this->orders->open(intval($order->id)))
$this->design->assign('message_error', 'error_open');
else
$this->orders->update_order($order->id, array('status'=>0));
}
elseif($new_status == 1)
{
if(!$this->orders->close(intval($order->id)))
$this->design->assign('message_error', 'error_closing');
else
$this->orders->update_order($order->id, array('status'=>1));
}
elseif($new_status == 2)
{
if(!$this->orders->close(intval($order->id)))
$this->design->assign('message_error', 'error_closing');
else
$this->orders->update_order($order->id, array('status'=>2));
}
elseif($new_status == 3)
{
if(!$this->orders->open(intval($order->id)))
$this->design->assign('message_error', 'error_open');
else
$this->orders->update_order($order->id, array('status'=>3));
header('Location: '.$this->request->get('return'));
}
$order = $this->orders->get_order($order->id);
// Отправляем письмо пользователю
$this->design->assign('additional_message', $this->request->post('additional_message'));
if($this->request->post('notify_user'))
$this->notify->email_order_user($order->id);
}
}
else
{
$order->id = $this->request->get('id', 'integer');
$order = $this->orders->get_order(intval($order->id));
// Метки заказа
$order_labels = array();
if(isset($order->id))
foreach($this->orders->get_order_labels($order->id) as $ol)
$order_labels[] = $ol->id;
}
$subtotal = 0;
$purchases_count = 0;
if($order && $purchases = $this->orders->get_purchases(array('order_id'=>$order->id)))
{
// Покупки
$products_ids = array();
$variants_ids = array();
foreach($purchases as $purchase)
{
$products_ids[] = $purchase->product_id;
$variants_ids[] = $purchase->variant_id;
}
$products = array();
foreach($this->products->get_products(array('id'=>$products_ids)) as $p)
$products[$p->id] = $p;
$images = $this->products->get_images(array('product_id'=>$products_ids));
foreach($images as $image)
$products[$image->product_id]->images[] = $image;
$variants = array();
foreach($this->variants->get_variants(array('product_id'=>$products_ids)) as $v)
$variants[$v->id] = $v;
foreach($variants as $variant)
if(!empty($products[$variant->product_id]))
$products[$variant->product_id]->variants[] = $variant;
foreach($purchases as &$purchase)
{
$purchase->options = unserialize($purchase->options);
if(!empty($products[$purchase->product_id]))
$purchase->product = $products[$purchase->product_id];
if(!empty($variants[$purchase->variant_id]))
$purchase->variant = $variants[$purchase->variant_id];
$subtotal += $purchase->price*$purchase->amount;
$purchases_count += $purchase->amount;
}
}
else
{
$purchases = array();
}
$feat = $this->features->get_features(array('in_variant'=>1));
foreach($feat AS $fe){
$feat[$fe->id] = $fe;
}
$this->design->assign('features', $feat);
// Если новый заказ и передали get параметры
if(empty($order->id))
{
if(empty($order->phone))
$order->phone = $this->request->get('phone', 'string');
if(empty($order->name))
$order->name = $this->request->get('name', 'string');
if(empty($order->address))
$order->address = $this->request->get('address', 'string');
if(empty($order->email))
$order->email = $this->request->get('email', 'string');
}
$this->design->assign('purchases', $purchases);
$this->design->assign('purchases_count', $purchases_count);
$this->design->assign('subtotal', $subtotal);
$this->design->assign('order', $order);
if(!empty($order->id))
{
// Способ доставки
$delivery = $this->delivery->get_delivery($order->delivery_id);
$this->design->assign('delivery', $delivery);
// Способ оплаты
$payment_method = $this->payment->get_payment_method($order->payment_method_id);
if(!empty($payment_method))
{
$this->design->assign('payment_method', $payment_method);
// Валюта оплаты
$payment_currency = $this->money->get_currency(intval($payment_method->currency_id));
$this->design->assign('payment_currency', $payment_currency);
}
// Пользователь
if($order->user_id)
$this->design->assign('user', $this->users->get_user(intval($order->user_id)));
// Соседние заказы
$this->design->assign('next_order', $this->orders->get_next_order($order->id, $this->request->get('status', 'string')));
$this->design->assign('prev_order', $this->orders->get_prev_order($order->id, $this->request->get('status', 'string')));
}
// Все способы доставки
$deliveries = $this->delivery->get_deliveries();
$this->design->assign('deliveries', $deliveries);
// Все способы оплаты
$payment_methods = $this->payment->get_payment_methods();
$this->design->assign('payment_methods', $payment_methods);
// Метки заказов
$labels = $this->orders->get_labels();
$this->design->assign('labels', $labels);
$this->design->assign('order_labels', $order_labels);
if($this->request->get('view') == 'print')
return $this->design->fetch('order_print.tpl');
else
return $this->design->fetch('order.tpl');
}
}

114
simpla/OrdersAdmin.php Normal file
View File

@@ -0,0 +1,114 @@
<?PHP
require_once('api/Simpla.php');
########################################
class OrdersAdmin extends Simpla
{
public function fetch()
{
$filter = array();
$filter['page'] = max(1, $this->request->get('page', 'integer'));
$filter['limit'] = 40;
// Поиск
$keyword = $this->request->get('keyword', 'string');
if(!empty($keyword))
{
$filter['keyword'] = $keyword;
$this->design->assign('keyword', $keyword);
}
// Фильтр по метке
$label = $this->orders->get_label($this->request->get('label'));
if(!empty($label))
{
$filter['label'] = $label->id;
$this->design->assign('label', $label);
}
// Обработка действий
if($this->request->method('post'))
{
// Действия с выбранными
$ids = $this->request->post('check');
if(is_array($ids))
switch($this->request->post('action'))
{
case 'delete':
{
foreach($ids as $id)
{
$o = $this->orders->get_order(intval($id));
if($o->status<3)
{
$this->orders->update_order($id, array('status'=>3));
$this->orders->open($id);
}
else
$this->orders->delete_order($id);
}
break;
}
case(preg_match('/^set_label_([0-9]+)/', $this->request->post('action'), $a) ? true : false):
{
$l_id = intval($a[1]);
if($l_id>0)
foreach($ids as $id)
{
$this->orders->add_order_labels($id, $l_id);
}
break;
}
case(preg_match('/^unset_label_([0-9]+)/', $this->request->post('action'), $a) ? true : false):
{
$l_id = intval($a[1]);
if($l_id>0)
foreach($ids as $id)
{
$this->orders->delete_order_labels($id, $l_id);
}
break;
}
}
}
if(empty($keyword))
{
$status = $this->request->get('status', 'integer');
$filter['status'] = $status;
$this->design->assign('status', $status);
}
$orders_count = $this->orders->count_orders($filter);
// Показать все страницы сразу
if($this->request->get('page') == 'all')
$filter['limit'] = $orders_count;
// Отображение
$orders = array();
foreach($this->orders->get_orders($filter) as $o)
$orders[$o->id] = $o;
// Метки заказов
$orders_labels = array();
foreach($this->orders->get_order_labels(array_keys($orders)) as $ol)
$orders[$ol->order_id]->labels[] = $ol;
$this->design->assign('pages_count', ceil($orders_count/$filter['limit']));
$this->design->assign('current_page', $filter['page']);
$this->design->assign('orders_count', $orders_count);
$this->design->assign('orders', $orders);
// Метки заказов
$labels = $this->orders->get_labels();
$this->design->assign('labels', $labels);
return $this->design->fetch('orders.tpl');
}
}

View File

@@ -0,0 +1,40 @@
<?PHP
require_once('api/Simpla.php');
class OrdersLabelAdmin extends Simpla
{
public function fetch()
{
$label->color = 'ffffff';
if($this->request->method('POST'))
{
$label->id = $this->request->post('id', 'integer');
$label->name = $this->request->post('name');
$label->color = $this->request->post('color');
if(empty($label->id))
{
$label->id = $this->orders->add_label($label);
$label = $this->orders->get_label($label->id);
$this->design->assign('message_success', 'added');
}
else
{
$this->orders->update_label($label->id, $label);
$label = $this->orders->get_label($label->id);
$this->design->assign('message_success', 'updated');
}
}
else
{
$id = $this->request->get('id', 'integer');
if(!empty($id))
$label = $this->orders->get_label(intval($id));
}
$this->design->assign('label', $label);
return $this->design->fetch('orders_label.tpl');
}
}

View File

@@ -0,0 +1,45 @@
<?PHP
require_once('api/Simpla.php');
########################################
class OrdersLabelsAdmin extends Simpla
{
public function fetch()
{
// Обработка действий
if($this->request->method('post'))
{
// Сортировка
$positions = $this->request->post('positions');
$ids = array_keys($positions);
sort($positions);
foreach($positions as $i=>$position)
$this->orders->update_label($ids[$i], array('position'=>$position));
// Действия с выбранными
$ids = $this->request->post('check');
if(is_array($ids))
switch($this->request->post('action'))
{
case 'delete':
{
foreach($ids as $id)
$this->orders->delete_label($id);
break;
}
}
}
// Отображение
$labels = $this->orders->get_labels();
$this->design->assign('labels', $labels);
return $this->design->fetch('orders_labels.tpl');
}
}
?>

226
simpla/PageAdmin.php Normal file
View File

@@ -0,0 +1,226 @@
<?PHP
require_once('api/Simpla.php');
class PageAdmin extends Simpla
{
private $allowed_image_extentions = array('png', 'gif', 'jpg', 'jpeg', 'ico');
public function fetch()
{
if($this->request->method('POST'))
{
$page->id = $this->request->post('id', 'integer');
$page->parent = $this->request->post('parent', 'integer');
$page->name = $this->request->post('name');
$page->header = $this->request->post('header');
$page->url = $this->request->post('url');
$page->meta_title = $this->request->post('meta_title');
$page->meta_keywords = $this->request->post('meta_keywords');
$page->meta_description = $this->request->post('meta_description');
$page->introtext = $this->request->post('introtext');
$page->toptext = $this->request->post('toptext');
$page->body = $this->request->post('body');
$page->bottext = $this->request->post('bottext');
$page->menu_id = $this->request->post('menu_id', 'integer');
$page->visible = $this->request->post('visible', 'boolean');
$page->show_home = $this->request->post('show_home', 'boolean');
$page->show_service = $this->request->post('show_service', 'boolean');
$page->works_url = $this->request->post('works_url');
$page->works_url_text = $this->request->post('works_url_text');
$page->body = str_replace('<p>&nbsp;</p>', '', $page->body); //
$page->body = str_replace('<div class="col-sm-6 mb">&nbsp;</div>', '', $page->body); // <div class="zooming2-title">'.$title.'</div>
$page->body = preg_replace('~<div class="col-sm-6 mb"><img(.*)src="(.*)/thumbs/400x300cp/(.*)"(.*)></div>~Uis', '<img$1src="$2/$3"$4>', $page->body);
$page->body = preg_replace('~<div class="col-sm-6 mb">.*<div class="zooming2-title">.*</div>.*<img(.*)src="(.*)/thumbs/400x300cp/(.*)"(.*)></div>~Uis', '<img$1src="$2/$3"$4>', $page->body);
// Связанные товары
if(is_array($this->request->post('related_products')))
{
foreach($this->request->post('related_products') as $p)
{
$rp[$p]->related_id = $p;
$rp[$p]->type = 'product';
}
$related_objects = $rp;
}
// Связанные статьи
if(is_array($this->request->post('related_pages')))
{
foreach($this->request->post('related_pages') as $p)
{
$rp[$p]->related_id = $p;
$rp[$p]->type = 'page';
}
$related_objects = $rp;
}
if(is_array($this->request->post('related_articles')))
{
foreach($this->request->post('related_articles') as $p)
{
$rp[$p]->related_id = $p;
$rp[$p]->type = 'article';
}
$related_objects = $rp;
}
## Не допустить одинаковые URL разделов.
if(($p = $this->pages->get_page($page->url)) && $p->id!=$page->id)
{
$this->design->assign('message_error', 'url_exists');
}
else
{
if(empty($page->id))
{
$page->id = $this->pages->add_page($page);
$page = $this->pages->get_page($page->id);
$this->design->assign('message_success', 'added');
}
else
{
$this->pages->update_page($page->id, $page);
$page = $this->pages->get_page($page->id);
$this->design->assign('message_success', 'updated');
}
// Удаление изображения
if($this->request->post('delete_image'))
{
$this->pages->delete_image($page->id);
}
// Загрузка изображения
$image = $this->request->files('image');
if(!empty($image['name']) && in_array(strtolower(pathinfo($image['name'], PATHINFO_EXTENSION)), $this->allowed_image_extentions))
{
if ($image_name = $this->image->upload_image($image['tmp_name'], $image['name']))
{
$this->pages->delete_image($page->id);
$this->pages->update_page($page->id, array('image'=>$image_name));
$page->image = $image_name;
}
else
{
$this->design->assign('error', 'error uploading image');
}
}
}
// Связанные объекты
$query = $this->db->placehold('DELETE FROM __pages_objects WHERE page_id=?', $page->id);
$this->db->query($query);
if(is_array($related_objects))
{
$pos = 0;
foreach($related_objects as $i=>$related_object)
$this->pages->add_related_object($page->id, $related_object->related_id, $related_object->type);
}
}
else
{
$id = $this->request->get('id', 'integer');
if(!empty($id))
$page = $this->pages->get_page(intval($id));
else
{
$page->menu_id = $this->request->get('menu_id');
$page->visible = 1;
}
}
//print_r($_FILES);print_r($page);die;
$this->design->assign('page', $page);
// Связанные объекты
$related_objects = $this->pages->get_related_objects(array('id'=>$page->id));
if(!empty($related_objects))
{
$r_products = array();
$r_pages = array();
$r_articles = array();
foreach($related_objects as &$r_p)
if($r_p->type == 'product') $r_products[$r_p->object_id] = &$r_p;
elseif($r_p->type == 'page') $r_pages[$r_p->object_id] = &$r_p;
elseif($r_p->type == 'article') $r_articles[$r_p->object_id] = &$r_p;
if(!empty($r_products)) {
$temp_products = $this->products->get_products(array('id'=>array_keys($r_products)));
foreach($temp_products as $temp_product)
$r_products[$temp_product->id] = $temp_product;
}
if(!empty($r_pages)) {
$temp_pages = $this->pages->get_pages(array('id'=>array_keys($r_pages)));
foreach($temp_pages as $temp_page)
$r_pages[$temp_page->id] = $temp_page;
}
if(!empty($r_articles)) {
$temp_pages = $this->articles->get_articles(array('id'=>array_keys($r_articles)));
foreach($temp_pages as $temp_page)
$r_articles[$temp_page->id] = $temp_page;
}
$page->body = preg_replace_callback('~<img.*class=.*zooming2[^>].*>~Uis', array($this, 'resizeBodyImages'), $page->body);
$this->design->assign('related_products', $r_products);
$this->design->assign('related_pages', $r_pages);
$this->design->assign('related_articles', $r_articles);
}
$menus = $this->pages->get_menus();
$this->design->assign('menus', $menus);
// Меню выбора родительской страницы (услуги)
$filter['parent'] = 28;
$select_items = $this->pages->get_select_pages($filter);
$this->design->assign('select_items', $select_items);
// Текущее меню
if(isset($page->menu_id))
$menu_id = $page->menu_id;
if(empty($menu_id) || !$menu = $this->pages->get_menu($menu_id))
{
$menu = reset($menus);
}
$this->design->assign('menu', $menu);
return $this->design->fetch('page.tpl');
}
function resizeBodyImages($m){
preg_match('~src=["\'](.*)["\']~Uis', $m[0], $img);
preg_match('~title=["\'](.*)["\']~Uis', $m[0], $title);
preg_match('~alt=["\'](.*)["\']~Uis', $m[0], $alt);
if(empty($img[1])) return $m[0];
$alt = isset($alt[1]) ? $alt[1] : '';
$title = isset($title[1]) ? $title[1] : '';
$src = Img::get(urldecode($img[1]), array('width' => 400, 'height' => 300, 'crop' => true));
$tl = $title ? '<div class="zooming2-title">'.$title.'</div>' : '';
return '<div class="col-sm-6 mb">'.$tl.'<img alt="'.$alt.'" class="zooming2" src="'.$src.'" title="'.$title.'"></div>' . "\n";
}
}

72
simpla/PagesAdmin.php Normal file
View File

@@ -0,0 +1,72 @@
<?PHP
require_once('api/Simpla.php');
########################################
class PagesAdmin extends Simpla
{
public function fetch()
{
// Меню
$menus = $this->pages->get_menus();
$this->design->assign('menus', $menus);
// Текущее меню
$menu_id = $this->request->get('menu_id', 'integer');
if(!$menu_id || !$menu = $this->pages->get_menu($menu_id))
{
$menu = reset($menus);
}
$this->design->assign('menu', $menu);
// Обработка действий
if($this->request->method('post'))
{
// Сортировка
$positions = $this->request->post('positions');
$ids = array_keys($positions);
sort($positions);
foreach($positions as $i=>$position)
$this->pages->update_page($ids[$i], array('position'=>$position));
// Действия с выбранными
$ids = $this->request->post('check');
if(is_array($ids))
switch($this->request->post('action'))
{
case 'disable':
{
$this->pages->update_page($ids, array('visible'=>0));
break;
}
case 'enable':
{
$this->pages->update_page($ids, array('visible'=>1));
break;
}
case 'delete':
{
foreach($ids as $id)
$this->pages->delete_page($id);
break;
}
}
}
// Отображение
$pages = $this->pages->get_pages(array('menu_id'=>$menu->id));
$this->design->assign('pages', $pages);
return $this->design->fetch('pages.tpl');
}
}
?>

View File

@@ -0,0 +1,71 @@
<?PHP
require_once('api/Simpla.php');
class PaymentMethodAdmin extends Simpla
{
public function fetch()
{
if($this->request->method('post'))
{
$payment_method->id = $this->request->post('id', 'intgeger');
$payment_method->enabled = $this->request->post('enabled', 'boolean');
$payment_method->name = $this->request->post('name');
$payment_method->currency_id = $this->request->post('currency_id');
$payment_method->description = $this->request->post('description');
$payment_method->module = $this->request->post('module', 'string');
$payment_settings = $this->request->post('payment_settings');
if(!$payment_deliveries = $this->request->post('payment_deliveries'))
$payment_deliveries = array();
if(empty($payment_method->id))
{
$payment_method->id = $this->payment->add_payment_method($payment_method);
$this->design->assign('message_success', 'Добавлено');
}
else
{
$this->payment->update_payment_method($payment_method->id, $payment_method);
$this->design->assign('message_success', 'Обновлено');
}
if($payment_method->id)
{
$this->payment->update_payment_settings($payment_method->id, $payment_settings);
$this->payment->update_payment_deliveries($payment_method->id, $payment_deliveries);
}
}
else
{
$payment_method->id = $this->request->get('id', 'integer');
if(!empty($payment_method->id))
{
$payment_method = $this->payment->get_payment_method($payment_method->id);
$payment_settings = $this->payment->get_payment_settings($payment_method->id);
}
else
{
$payment_settings = array();
}
$payment_deliveries = $this->payment->get_payment_deliveries($payment_method->id);
}
$this->design->assign('payment_deliveries', $payment_deliveries);
// Связанные способы доставки
$deliveries = $this->delivery->get_deliveries();
$this->design->assign('deliveries', $deliveries);
$this->design->assign('payment_method', $payment_method);
$this->design->assign('payment_settings', $payment_settings);
$payment_modules = $this->payment->get_payment_modules();
$this->design->assign('payment_modules', $payment_modules);
$currencies = $this->money->get_currencies();
$this->design->assign('currencies', $currencies);
return $this->design->fetch('payment_method.tpl');
}
}

View File

@@ -0,0 +1,59 @@
<?PHP
require_once('api/Simpla.php');
########################################
class PaymentMethodsAdmin extends Simpla
{
public function fetch()
{
// Обработка действий
if($this->request->method('post'))
{
// Сортировка
$positions = $this->request->post('positions');
$ids = array_keys($positions);
sort($positions);
foreach($positions as $i=>$position)
$this->payment->update_payment_method($ids[$i], array('position'=>$position));
// Действия с выбранными
$ids = $this->request->post('check');
if(is_array($ids))
switch($this->request->post('action'))
{
case 'disable':
{
$this->payment->update_payment_method($ids, array('enabled'=>0));
break;
}
case 'enable':
{
$this->payment->update_payment_method($ids, array('enabled'=>1));
break;
}
case 'delete':
{
foreach($ids as $id)
$this->payment->delete_payment_method($id);
break;
}
}
}
// Отображение
$payment_methods = $this->payment->get_payment_methods();
$this->design->assign('payment_methods', $payment_methods);
return $this->design->fetch('payment_methods.tpl');
}
}
?>

85
simpla/PostAdmin.php Normal file
View File

@@ -0,0 +1,85 @@
<?PHP
require_once('api/Simpla.php');
class PostAdmin extends Simpla
{
private $allowed_image_extentions = array('png', 'gif', 'jpg', 'jpeg', 'ico');
public function fetch()
{
if($this->request->method('post'))
{
$post->id = $this->request->post('id', 'integer');
$post->name = $this->request->post('name');
$post->date = date('Y-m-d', strtotime($this->request->post('date')));
$post->visible = $this->request->post('visible', 'boolean');
$post->url = $this->request->post('url', 'string');
$post->meta_title = $this->request->post('meta_title');
$post->meta_keywords = $this->request->post('meta_keywords');
$post->meta_description = $this->request->post('meta_description');
$post->annotation = $this->request->post('annotation');
$post->text = $this->request->post('body');
// Не допустить одинаковые URL разделов.
if(($a = $this->blog->get_post($post->url)) && $a->id!=$post->id)
{
$this->design->assign('message_error', 'url_exists');
}
else
{
if(empty($post->id))
{
$post->id = $this->blog->add_post($post);
$post = $this->blog->get_post($post->id);
$this->design->assign('message_success', 'added');
}
else
{
$this->blog->update_post($post->id, $post);
$post = $this->blog->get_post($post->id);
$this->design->assign('message_success', 'updated');
}
// Удаление изображения
if($this->request->post('delete_image'))
{
$this->blog->delete_image($post->id);
}
// Загрузка изображения
$image = $this->request->files('image');
if(!empty($image['name']) && in_array(strtolower(pathinfo($image['name'], PATHINFO_EXTENSION)), $this->allowed_image_extentions))
{
if ($image_name = $this->image->upload_image($image['tmp_name'], $image['name']))
{
$this->blog->delete_image($post->id);
$this->blog->update_post($post->id, array('image'=>$image_name));
}
else
{
$this->design->assign('error', 'error uploading image');
}
}
$post = $this->blog->get_post(intval($post->id));
}
}
else
{
$post->id = $this->request->get('id', 'integer');
$post = $this->blog->get_post(intval($post->id));
if(!$post->id) $post->visible = 1;
}
if(empty($post->date))
$post->date = date($this->settings->date_format, time());
$this->design->assign('post', $post);
return $this->design->fetch('post.tpl');
}
}

267
simpla/PreorderAdmin.php Normal file
View File

@@ -0,0 +1,267 @@
<?PHP
require_once('api/Simpla.php');
############################################
# Class Product - edit the static section
############################################
class PreorderAdmin extends Simpla
{
public function fetch()
{
if($this->request->method('post'))
{
/* $order->id = $this->request->post('id', 'integer');
$order->name = $this->request->post('name');
$order->email = $this->request->post('email');
$order->phone = $this->request->post('phone');
$order->address = $this->request->post('address');
$order->comment = $this->request->post('comment');
$order->note = $this->request->post('note');
$order->discount = $this->request->post('discount', 'floatr');
$order->coupon_discount = $this->request->post('coupon_discount', 'floatr');
$order->delivery_id = $this->request->post('delivery_id', 'integer');
$order->delivery_price = $this->request->post('delivery_price', 'float');
$order->payment_method_id = $this->request->post('payment_method_id', 'integer');
$order->paid = $this->request->post('paid', 'integer');
$order->user_id = $this->request->post('user_id', 'integer');
$order->separate_delivery = $this->request->post('separate_delivery', 'integer');
if(!$order_labels = $this->request->post('order_labels'))
$order_labels = array();
if(empty($order->id))
{
$order->id = $this->orders->add_order($order);
$this->design->assign('message_success', 'added');
}
else
{
$this->orders->update_order($order->id, $order);
$this->design->assign('message_success', 'updated');
}
$this->orders->update_order_labels($order->id, $order_labels);
if($order->id)
{
// Покупки
$purchases = array();
if($this->request->post('purchases'))
{
foreach($this->request->post('purchases') as $n=>$va) foreach($va as $i=>$v)
$purchases[$i]->$n = $v;
}
$posted_purchases_ids = array();
foreach($purchases as $purchase)
{
$variant = $this->variants->get_variant($purchase->variant_id);
if(!empty($purchase->id))
if(!empty($variant))
$this->orders->update_purchase($purchase->id, array('variant_id'=>$purchase->variant_id, 'variant_name'=>$variant->name, 'price'=>$purchase->price, 'amount'=>$purchase->amount));
else
$this->orders->update_purchase($purchase->id, array('price'=>$purchase->price, 'amount'=>$purchase->amount));
else
$purchase->id = $this->orders->add_purchase(array('order_id'=>$order->id, 'variant_id'=>$purchase->variant_id, 'variant_name'=>$variant->name, 'price'=>$purchase->price, 'amount'=>$purchase->amount));
$posted_purchases_ids[] = $purchase->id;
}
// Удалить непереданные товары
foreach($this->orders->get_purchases(array('order_id'=>$order->id)) as $p)
if(!in_array($p->id, $posted_purchases_ids))
$this->orders->delete_purchase($p->id);
// Принять?
if($this->request->post('status_new'))
$new_status = 0;
elseif($this->request->post('status_accept'))
$new_status = 1;
elseif($this->request->post('status_done'))
$new_status = 2;
elseif($this->request->post('status_deleted'))
$new_status = 3;
else
$new_status = $this->request->post('status', 'string');
if($new_status == 0)
{
if(!$this->orders->open(intval($order->id)))
$this->design->assign('message_error', 'error_open');
else
$this->orders->update_order($order->id, array('status'=>0));
}
elseif($new_status == 1)
{
if(!$this->orders->close(intval($order->id)))
$this->design->assign('message_error', 'error_closing');
else
$this->orders->update_order($order->id, array('status'=>1));
}
elseif($new_status == 2)
{
if(!$this->orders->close(intval($order->id)))
$this->design->assign('message_error', 'error_closing');
else
$this->orders->update_order($order->id, array('status'=>2));
}
elseif($new_status == 3)
{
if(!$this->orders->open(intval($order->id)))
$this->design->assign('message_error', 'error_open');
else
$this->orders->update_order($order->id, array('status'=>3));
header('Location: '.$this->request->get('return'));
}
$order = $this->orders->get_order($order->id);
// Отправляем письмо пользователю
$this->design->assign('additional_message', $this->request->post('additional_message'));
if($this->request->post('notify_user'))
$this->notify->email_order_user($order->id);
}
*/
}
else
{
$order->id = $this->request->get('id', 'integer');
//echo $order->id; die;
$this->db->query("SELECT * FROM __preorders WHERE id='".$order->id."'");
$order = $this->db->result();
$order->status = 999;
//$order = $this->orders->get_order(intval($order->id));
// Метки заказа
$order_labels = array();
if(isset($order->id))
foreach($this->orders->get_order_labels($order->id) as $ol)
$order_labels[] = $ol->id;
}
$subtotal = 0;
$purchases_count = 0;
$purchases = json_decode($order->products); //print_r($purchases);die;
if($order && $purchases)
{
// Покупки
$products_ids = array();
$variants_ids = array();
foreach($purchases as $kid => $purchase)
{ $this->db->query("SELECT product_id FROM __variants WHERE id = '$kid' ");
$x = $this->db->result();
$products_ids[] = $x->product_id;
$purchases->$kid->product_id = $x->product_id;
$variants_ids[] = $purchase->variant_id;
}
$products = array();
foreach($this->products->get_products(array('id'=>$products_ids)) as $p){
$products[$p->id] = $p;
foreach($purchases as $kid => $purchase) if($purchases->$kid->product_id == $p->id) {$purchases->$kid->product = $p; $purchases->$kid->product_name = $p->name;}
}
//print_r($purchases);
$images = $this->products->get_images(array('product_id'=>$products_ids));
foreach($images as $image)
$products[$image->product_id]->images[] = $image;
$variants = array();
foreach($this->variants->get_variants(array('product_id'=>$products_ids)) as $v)
$variants[$v->id] = $v;
foreach($variants as $variant)
if(!empty($products[$variant->product_id]))
$products[$variant->product_id]->variants[] = $variant;
foreach($purchases as &$purchase)
{
$purchase->options = unserialize($purchase->options);
if(!empty($products[$purchase->product_id]))
$purchase->product = $products[$purchase->product_id];
if(!empty($variants[$purchase->variant_id]))
$purchase->variant = $variants[$purchase->variant_id];
$subtotal += $purchase->price*$purchase->amount;
$purchases_count += $purchase->amount;
}
}
else
{
$purchases = array();
}
$feat = $this->features->get_features(array('in_variant'=>1));
foreach($feat AS $fe){
$feat[$fe->id] = $fe;
}
$this->design->assign('features', $feat);
// Если новый заказ и передали get параметры
if(empty($order->id))
{
if(empty($order->phone))
$order->phone = $this->request->get('phone', 'string');
if(empty($order->name))
$order->name = $this->request->get('name', 'string');
if(empty($order->address))
$order->address = $this->request->get('address', 'string');
if(empty($order->email))
$order->email = $this->request->get('email', 'string');
}
$this->design->assign('purchases', $purchases);
$this->design->assign('purchases_count', $purchases_count);
$this->design->assign('subtotal', $subtotal);
$this->design->assign('order', $order);
if(!empty($order->id))
{
// Способ доставки
$delivery = $this->delivery->get_delivery($order->delivery_id);
$this->design->assign('delivery', $delivery);
// Способ оплаты
$payment_method = $this->payment->get_payment_method($order->payment_method_id);
if(!empty($payment_method))
{
$this->design->assign('payment_method', $payment_method);
// Валюта оплаты
$payment_currency = $this->money->get_currency(intval($payment_method->currency_id));
$this->design->assign('payment_currency', $payment_currency);
}
// Пользователь
if($order->user_id)
$this->design->assign('user', $this->users->get_user(intval($order->user_id)));
// Соседние заказы
$this->design->assign('next_order', $this->orders->get_next_order($order->id, $this->request->get('status', 'string')));
$this->design->assign('prev_order', $this->orders->get_prev_order($order->id, $this->request->get('status', 'string')));
}
// Все способы доставки
$deliveries = $this->delivery->get_deliveries();
$this->design->assign('deliveries', $deliveries);
// Все способы оплаты
$payment_methods = $this->payment->get_payment_methods();
$this->design->assign('payment_methods', $payment_methods);
// Метки заказов
$labels = $this->orders->get_labels();
$this->design->assign('labels', $labels);
$this->design->assign('order_labels', $order_labels);
if($this->request->get('view') == 'print')
return $this->design->fetch('order_print.tpl');
else
return $this->design->fetch('order.tpl');
}
}

87
simpla/PreordersAdmin.php Normal file
View File

@@ -0,0 +1,87 @@
<?PHP
require_once('api/Simpla.php');
########################################
class PreordersAdmin extends Simpla
{
public function fetch()
{
$filter = array();
$filter['page'] = max(1, $this->request->get('page', 'integer'));
$filter['limit'] = 40;
// Поиск
$keyword = $this->request->get('keyword', 'string');
if(!empty($keyword))
{
$filter['keyword'] = $keyword;
$this->design->assign('keyword', $keyword);
}
// Фильтр по метке
$label = $this->orders->get_label($this->request->get('label'));
if(!empty($label))
{
$filter['label'] = $label->id;
$this->design->assign('label', $label);
}
// Обработка действий
if($this->request->method('post'))
{
// Действия с выбранными
$ids = $this->request->post('check');
if(is_array($ids))
switch($this->request->post('action'))
{
case 'delete':
{ //print_r($_POST); die;
foreach($ids as $id)
{
$this->db->query("DELETE FROM __preorders WHERE id='$id'");
}
break;
}
}
}
if(empty($keyword))
{
$status = $this->request->get('status', 'integer');
$filter['status'] = $status;
$this->design->assign('status', $status);
}
$orders_count = $this->orders->count_orders($filter);
// Показать все страницы сразу
if($this->request->get('page') == 'all')
$filter['limit'] = $orders_count;
// Отображение
$orders = array();
foreach($this->orders->get_orders($filter) as $o)
$orders[$o->id] = $o;
// Метки заказов
$orders_labels = array();
foreach($this->orders->get_order_labels(array_keys($orders)) as $ol)
$orders[$ol->order_id]->labels[] = $ol;
$this->design->assign('pages_count', ceil($orders_count/$filter['limit']));
$this->design->assign('current_page', $filter['page']);
$this->design->assign('orders_count', $orders_count);
$this->design->assign('orders', $orders);
// Метки заказов
$labels = $this->orders->get_labels();
$this->design->assign('labels', $labels);
return $this->design->fetch('orders.tpl');
}
}

466
simpla/ProductAdmin.php Normal file
View File

@@ -0,0 +1,466 @@
<?PHP
require_once('api/Simpla.php');
############################################
# Class Product - edit the static section
############################################ biksenonovye-linzy-dlya-audi-a3-bl01
class ProductAdmin extends Simpla
{
public function fetch()
{
$options = array();
$product_categories = array();
$variants = array();
$images = array();
$product_features = array();
$related_products = array();
$related_articles = array();
if($this->request->method('post') && !empty($_POST))
{
$product->id = $this->request->post('id', 'integer');
$product->name = $this->request->post('name');
$product->visible = $this->request->post('visible', 'boolean');
$product->featured = $this->request->post('featured');
$product->brand_id = $this->request->post('brand_id', 'integer');
$product->ym = $this->request->post('ym', 'boolean');
$product->url = $this->request->post('url', 'string');
$product->meta_title = $this->request->post('meta_title');
$product->meta_keywords = $this->request->post('meta_keywords');
$product->meta_description = $this->request->post('meta_description');
$product->product_h1 = $this->request->post('product_h1');
$product->annotation = $this->request->post('annotation');
$product->body = $this->request->post('body');
// Варианты товара
if($this->request->post('variants'))
foreach($this->request->post('variants') as $n=>$va) foreach($va as $i=>$v)
$variants[$i]->$n = $v;
// Категории товара
$product_categories = $this->request->post('categories');
if(is_array($product_categories))
{
foreach($product_categories as $c)
$pc[]->id = $c;
$product_categories = $pc;
}
// Свойства товара
$options = $this->request->post('options');
if(is_array($options))
{
foreach($options as $f_id=>$val)
{
$po[$f_id]->feature_id = $f_id;
$po[$f_id]->value = $val;
}
$options = $po;
}
// Связанные товары
if(is_array($this->request->post('related_products')))
{
foreach($this->request->post('related_products') as $p)
{
$rp[$p]->product_id = $product->id;
$rp[$p]->related_id = $p;
}
$related_products = $rp;
}
// Связанные Статьи
if(is_array($this->request->post('related_articles')))
{
foreach($this->request->post('related_articles') as $p)
{
$rs[$p]->object_id = $product->id;
$rs[$p]->article_id = $p;
$rs[$p]->type = 'product';
}
$related_articles = $rs;
}
// Не допустить пустое название товара.
if(empty($product->name))
{
$this->design->assign('message_error', 'empty_name');
if(!empty($product->id))
$images = $this->products->get_images(array('product_id'=>$product->id));
}
// Не допустить одинаковые URL разделов.
elseif(($p = $this->products->get_product($product->url)) && $p->id!=$product->id)
{
$this->design->assign('message_error', 'url_exists');
if(!empty($product->id))
$images = $this->products->get_images(array('product_id'=>$product->id));
}
else
{
if(empty($product->id))
{
$product->id = $this->products->add_product($product);
$product = $this->products->get_product($product->id);
$this->design->assign('message_success', 'added');
}
else
{
$this->products->update_product($product->id, $product);
$product = $this->products->get_product($product->id);
$this->design->assign('message_success', 'updated');
}
if($product->id)
{
// Категории товара
$query = $this->db->placehold('DELETE FROM __products_categories WHERE product_id=?', $product->id);
$this->db->query($query);
if(is_array($product_categories))
{
foreach($product_categories as $i=>$category)
$this->categories->add_product_category($product->id, $category->id, $i);
}
// Варианты
if(is_array($variants))
{
$variants_ids = array();
foreach($variants as $index=>&$variant)
{
if($variant->stock == '∞' || $variant->stock == '')
$variant->stock = null;
// Удалить файл
if(!empty($_POST['delete_attachment'][$index]))
{
$this->variants->delete_attachment($variant->id);
}
// Загрузить файлы
if(!empty($_FILES['attachment']['tmp_name'][$index]) && !empty($_FILES['attachment']['name'][$index]))
{
$attachment_tmp_name = $_FILES['attachment']['tmp_name'][$index];
$attachment_name = $_FILES['attachment']['name'][$index];
move_uploaded_file($attachment_tmp_name, $this->config->root_dir.'/'.$this->config->downloads_dir.$attachment_name);
$variant->attachment = $attachment_name;
}
if($variant->id)
{
$this->variants->update_variant($variant->id, $variant);
}
else
{
$variant->product_id = $product->id;
$variant->id = $this->variants->add_variant($variant);
}
$variant = $this->variants->get_variant($variant->id);
$variants_ids[] = $variant->id;
}
// Удалить непереданные варианты
$current_variants = $this->variants->get_variants(array('product_id'=>$product->id));
foreach($current_variants as $current_variant)
if(!in_array($current_variant->id, $variants_ids))
$this->variants->delete_variant($current_variant->id);
// Отсортировать варианты
asort($variants_ids);
$i = 0;
foreach($variants_ids as $variant_id)
{
$this->variants->update_variant($variants_ids[$i], array('position'=>$variant_id));
$i++;
}
// Добавление значений свойств вариантов
if(is_array($variants))
{
foreach($variants AS $v)
$vars[] = $v;
$this->features->delete_variant_options($product->id);
$options2 = (array)$this->request->post('options2');
foreach($options2 AS $i=>$opts){
$v=0;
foreach($opts AS $opt){
if(($opt) && $opt!='endoptions'){
$temp[$v][$i][] = $opt;
if($vars[$v]->id)
$this->features->update_variant_option($vars[$v]->id, $i, $opt);
}elseif($opt=='endoptions'){
$v++;
}
}
}
//print_r($temp);
}
}
// Удаление изображений
$images = (array)$this->request->post('images');
$current_images = $this->products->get_images(array('product_id'=>$product->id));
foreach($current_images as $image)
{
if(!in_array($image->id, $images))
$this->products->delete_image($image->id);
}
// Порядок изображений
if($images = $this->request->post('images'))
{
$i=0;
foreach($images as $id)
{
$this->products->update_image($id, array('position'=>$i));
$i++;
}
}
// Загрузка изображений
if($images = $this->request->files('images'))
{
for($i=0; $i<count($images['name']); $i++)
{
if ($image_name = $this->image->upload_image($images['tmp_name'][$i], $images['name'][$i]))
{
$this->products->add_image($product->id, $image_name);
}
else
{
$this->design->assign('error', 'error uploading image');
}
}
}
// Загрузка изображений из интернета
if($images = $this->request->post('images_urls'))
{
foreach($images as $url)
{
if(!empty($url) && $url != 'http://')
$this->products->add_image($product->id, $url);
}
}
$images = $this->products->get_images(array('product_id'=>$product->id));
// Характеристики товара
// Удалим все из товара
foreach($this->features->get_product_options($product->id) as $po)
$this->features->delete_option($product->id, $po->feature_id);
// Свойства текущей категории
$category_features = array();
foreach($this->features->get_features(array('category_id'=>$product_categories[0])) as $f)
$category_features[] = $f->id;
if(is_array($options))
foreach($options as $option)
{
if(in_array($option->feature_id, $category_features))
$this->features->update_option($product->id, $option->feature_id, $option->value);
}
// Новые характеристики
$new_features_names = $this->request->post('new_features_names');
$new_features_values = $this->request->post('new_features_values');
if(is_array($new_features_names) && is_array($new_features_values))
{
foreach($new_features_names as $i=>$name)
{
$value = trim($new_features_values[$i]);
if(!empty($name) && !empty($value))
{
$query = $this->db->placehold("SELECT * FROM __features WHERE name=? LIMIT 1", trim($name));
$this->db->query($query);
$feature_id = $this->db->result('id');
if(empty($feature_id))
{
$feature_id = $this->features->add_feature(array('name'=>trim($name)));
}
$this->features->add_feature_category($feature_id, reset($product_categories)->id);
$this->features->update_option($product->id, $feature_id, $value);
}
}
// Свойства товара
$options = $this->features->get_product_options($product->id);
}
// Связанные товары
$query = $this->db->placehold('DELETE FROM __related_products WHERE product_id=?', $product->id);
$this->db->query($query);
if(is_array($related_products))
{
$pos = 0;
foreach($related_products as $i=>$related_product)
$this->products->add_related_product($product->id, $related_product->related_id, $pos++);
}
// Связанные Статьи
$query = $this->db->placehold('DELETE FROM __article_objects WHERE object_id=?', $product->id);
$this->db->query($query);
if(is_array($related_articles))
{
$pos = 0;
foreach($related_articles as $i=>$related_article)
$this->articles->add_related_object($related_article->article_id, $product->id, $related_article->type);
}
}
}
$options2 = $this->features->get_product_variant_options($product->id);
//header('Location: '.$this->request->url(array('message_success'=>'updated')));
}
else
{
$product->id = $this->request->get('id', 'integer');
$product = $this->products->get_product(intval($product->id));
//print_r($product);die;
if($product && $product->id)
{
// Категории товара
$product_categories = $this->categories->get_categories(array('product_id'=>$product->id));
// Варианты товара
$variants = $this->variants->get_variants(array('product_id'=>$product->id));
// Изображения товара
$images = $this->products->get_images(array('product_id'=>$product->id));
// Свойства товара
$options = $this->features->get_options(array('product_id'=>$product->id));
$options2 = $this->features->get_product_variant_options($product->id);
// Связанные товары
$related_products = $this->products->get_related_products(array('product_id'=>$product->id));
// Связанные товары
$related_articles = $this->articles->get_related_articles(array('id'=>$product->id,'type'=>'product'));
}
else
{
// Сразу активен
$product->visible = 1;
}
}
if(empty($variants))
$variants = array(1);
if(empty($product_categories))
{
if($category_id = $this->request->get('category_id'))
$product_categories[0]->id = $category_id;
else
$product_categories = array(1);
}
if(empty($product->brand_id) && $brand_id=$this->request->get('brand_id'))
{
$product->brand_id = $brand_id;
}
if(!empty($related_products))
{
foreach($related_products as &$r_p)
$r_products[$r_p->related_id] = &$r_p;
$temp_products = $this->products->get_products(array('id'=>array_keys($r_products)));
foreach($temp_products as $temp_product)
$r_products[$temp_product->id] = $temp_product;
$related_products_images = $this->products->get_images(array('product_id'=>array_keys($r_products)));
foreach($related_products_images as $image)
{
$r_products[$image->product_id]->images[] = $image;
}
}
if(is_array($options))
{
$temp_options = array();
foreach($options as $option)
$temp_options[$option->feature_id] = $option;
$options = $temp_options;
}
$this->design->assign('product', $product);
$this->design->assign('product_categories', $product_categories);
$this->design->assign('product_variants', $variants);
$this->design->assign('product_images', $images);
$this->design->assign('options', $options);
$this->design->assign('related_products', $related_products);
// Все бренды
$brands = $this->brands->get_brands();
$this->design->assign('brands', $brands);
// Все категории
$categories = $this->categories->get_categories_tree();
$this->design->assign('categories', $categories);
// Все свойства
$features = $this->features->get_features();
$this->design->assign('features', $features);
if($product_categories){
$cat = reset($product_categories);
$features2 = $this->features->get_features(array('category_id'=>$cat->id,'in_variant'=>1));
}else{
$features2 = array();
}
//print_r($features2);
$this->design->assign('features2', $features2);
if(is_array($options2))
{
foreach($options2 as $option)
$temp_options[$option->id_veriant][$option->feature_id][] = $option;
$options2 = $temp_options;
}
$this->design->assign('options2', $options2);
// Связка категорий со свойствами
$categories_features = array();
$query = $this->db->placehold('SELECT category_id, feature_id FROM __categories_features');
$this->db->query($query);
$c_f = $this->db->results();
foreach($c_f as $i)
{
$categories_features[$i->category_id][] = $i->feature_id;
}
$this->design->assign('categories_features', $categories_features);
//$this->design->assign('message_success', $this->request->get('message_success', 'string'));
//$this->design->assign('message_error', $this->request->get('message_error', 'string'));
if(!empty($related_articles)) {
foreach($related_articles as $related_a)
$r_articles[$related_a->article_id] = $related_a;
$temp_articles = $this->articles->get_articles(array('id'=>array_keys($r_articles)));
foreach($temp_articles as $temp_article)
$r_articles[$temp_article->id] = $temp_article;
}
$this->design->assign('related_articles', $r_articles);
return $this->design->fetch('product.tpl');
}
}

252
simpla/ProductsAdmin.php Normal file
View File

@@ -0,0 +1,252 @@
<?PHP
require_once('api/Simpla.php');
class ProductsAdmin extends Simpla
{
function fetch()
{
$filter = array();
$filter['page'] = max(1, $this->request->get('page', 'integer'));
$filter['limit'] = $this->settings->products_num_admin;
// Категории
$categories = $this->categories->get_categories_tree();
$this->design->assign('categories', $categories);
// Текущая категория
$category_id = $this->request->get('category_id', 'integer');
if($category_id && $category = $this->categories->get_category($category_id))
$filter['category_id'] = $category->children;
// Бренды категории
$brands = $this->brands->get_brands(array('category_id'=>$category_id));
$this->design->assign('brands', $brands);
// Все бренды
$all_brands = $this->brands->get_brands();
$this->design->assign('all_brands', $all_brands);
// Текущий бренд
$brand_id = $this->request->get('brand_id', 'integer');
if($brand_id && $brand = $this->brands->get_brand($brand_id))
$filter['brand_id'] = $brand->id;
// Текущий фильтр
if($f = $this->request->get('filter', 'string'))
{
if($f == 'featured')
$filter['featured'] = 1;
elseif($f == 'discounted')
$filter['discounted'] = 1;
$this->design->assign('filter', $f);
}
// Поиск
$keyword = $this->request->get('keyword');
if(!empty($keyword))
{
$filter['keyword'] = $keyword;
$this->design->assign('keyword', $keyword);
}
// Обработка действий
if($this->request->method('post'))
{
// Сохранение цен и наличия
$prices = $this->request->post('price');
$stocks = $this->request->post('stock');
foreach($prices as $id=>$price)
{
$stock = $stocks[$id];
if($stock == '∞' || $stock == '')
$stock = null;
$this->variants->update_variant($id, array('price'=>$price, 'stock'=>$stock));
}
// Сортировка
$positions = $this->request->post('positions');
$ids = array_keys($positions);
sort($positions);
$positions = array_reverse($positions);
foreach($positions as $i=>$position)
$this->products->update_product($ids[$i], array('position'=>$position));
// Действия с выбранными
$ids = $this->request->post('check');
if(!empty($ids))
switch($this->request->post('action'))
{
case 'disable':
{
$this->products->update_product($ids, array('visible'=>0));
break;
}
case 'enable':
{
$this->products->update_product($ids, array('visible'=>1));
break;
}
case 'set_featured':
{
$this->products->update_product($ids, array('featured'=>1));
break;
}
case 'unset_featured':
{
$this->products->update_product($ids, array('featured'=>0));
break;
}
case 'delete':
{
foreach($ids as $id)
$this->products->delete_product($id);
break;
}
case 'duplicate':
{
foreach($ids as $id)
$this->products->duplicate_product(intval($id));
break;
}
case 'move_to_page':
{
$target_page = $this->request->post('target_page', 'integer');
// Сразу потом откроем эту страницу
$filter['page'] = $target_page;
// До какого товара перемещать
$limit = $filter['limit']*($target_page-1);
if($target_page > $this->request->get('page', 'integer'))
$limit += count($ids)-1;
else
$ids = array_reverse($ids, true);
$temp_filter = $filter;
$temp_filter['page'] = $limit+1;
$temp_filter['limit'] = 1;
$target_product = array_pop($this->products->get_products($temp_filter));
$target_position = $target_product->position;
// Если вылезли за последний товар - берем позицию последнего товара в качестве цели перемещения
if($target_page > $this->request->get('page', 'integer') && !$target_position)
{
$query = $this->db->placehold("SELECT distinct p.position AS target FROM __products p LEFT JOIN __products_categories AS pc ON pc.product_id = p.id WHERE 1 $category_id_filter $brand_id_filter ORDER BY p.position DESC LIMIT 1", count($ids));
$this->db->query($query);
$target_position = $this->db->result('target');
}
foreach($ids as $id)
{
$query = $this->db->placehold("SELECT position FROM __products WHERE id=? LIMIT 1", $id);
$this->db->query($query);
$initial_position = $this->db->result('position');
if($target_position > $initial_position)
$query = $this->db->placehold(" UPDATE __products set position=position-1 WHERE position>? AND position<=?", $initial_position, $target_position);
else
$query = $this->db->placehold(" UPDATE __products set position=position+1 WHERE position<? AND position>=?", $initial_position, $target_position);
$this->db->query($query);
$query = $this->db->placehold("UPDATE __products SET __products.position = ? WHERE __products.id = ?", $target_position, $id);
$this->db->query($query);
}
break;
}
case 'move_to_category':
{
$category_id = $this->request->post('target_category', 'integer');
$filter['page'] = 1;
$category = $this->categories->get_category($category_id);
$filter['category_id'] = $category->children;
foreach($ids as $id)
{
$query = $this->db->placehold("DELETE FROM __products_categories WHERE category_id=? AND product_id=? LIMIT 1", $category_id, $id);
$this->db->query($query);
$query = $this->db->placehold("UPDATE IGNORE __products_categories set category_id=? WHERE product_id=? ORDER BY position DESC LIMIT 1", $category_id, $id);
$this->db->query($query);
if($this->db->affected_rows() == 0)
$query = $this->db->query("INSERT IGNORE INTO __products_categories set category_id=?, product_id=?", $category_id, $id);
}
break;
}
case 'move_to_brand':
{
$brand_id = $this->request->post('target_brand', 'integer');
$brand = $this->brands->get_brand($brand_id);
$filter['page'] = 1;
$filter['brand_id'] = $brand_id;
$query = $this->db->placehold("UPDATE __products set brand_id=? WHERE id in (?@)", $brand_id, $ids);
$this->db->query($query);
// Заново выберем бренды категории
$brands = $this->brands->get_brands(array('category_id'=>$category_id));
$this->design->assign('brands', $brands);
break;
}
}
}
// Отображение
if(isset($brand))
$this->design->assign('brand', $brand);
if(isset($category))
$this->design->assign('category', $category);
$products_count = $this->products->count_products($filter);
// Показать все страницы сразу
if($this->request->get('page') == 'all')
$filter['limit'] = $products_count;
$pages_count = ceil($products_count/$filter['limit']);
$filter['page'] = min($filter['page'], $pages_count);
$this->design->assign('products_count', $products_count);
$this->design->assign('pages_count', $pages_count);
$this->design->assign('current_page', $filter['page']);
$products = array();
foreach($this->products->get_products($filter) as $p)
$products[$p->id] = $p;
if(!empty($products))
{
// Товары
$products_ids = array_keys($products);
foreach($products as &$product)
{
$product->variants = array();
$product->images = array();
$product->properties = array();
}
$variants = $this->variants->get_variants(array('product_id'=>$products_ids));
foreach($variants as &$variant)
{
$products[$variant->product_id]->variants[] = $variant;
}
$images = $this->products->get_images(array('product_id'=>$products_ids));
foreach($images as $image)
$products[$image->product_id]->images[$image->id] = $image;
}
$this->design->assign('products', $products);
return $this->design->fetch('products.tpl');
}
}

207
simpla/ServiceAdmin.php Normal file
View File

@@ -0,0 +1,207 @@
<?PHP
require_once('api/Simpla.php');
class ServiceAdmin extends Simpla
{
private $allowed_image_extentions = array('png', 'gif', 'jpg', 'jpeg', 'ico');
public function fetch()
{
if ($this->request->method('POST')) {
$id = $this->request->post('id', 'integer');
$db_page = $this->services->get($id);
$page = new stdClass();
$page->id = $id;
$page->parent = $this->request->post('parent', 'integer');
$page->name = $this->request->post('name');
$page->header = $this->request->post('header');
$page->url = $this->request->post('url');
$page->meta_title = $this->request->post('meta_title');
$page->meta_keywords = $this->request->post('meta_keywords');
$page->meta_description = $this->request->post('meta_description');
$page->introtext = $this->request->post('introtext');
$page->toptext = $this->request->post('toptext');
$page->body = $this->request->post('body');
$page->bottext = $this->request->post('bottext');
$page->menu_id = $this->services->menu_id;
$page->visible = $this->request->post('visible', 'boolean');
$page->show_home = $this->request->post('show_home', 'boolean');
$page->show_service = $this->request->post('show_service', 'boolean');
$page->works_url = $this->request->post('works_url');
$page->works_url_text = $this->request->post('works_url_text');
$page->body = str_replace('<p>&nbsp;</p>', '', $page->body); //
$page->body = str_replace('<div class="col-sm-6 mb">&nbsp;</div>', '', $page->body); // <div class="zooming2-title">'.$title.'</div>
$page->body = preg_replace('~<div class="col-sm-6 mb"><img(.*)src="(.*)/thumbs/400x300cp/(.*)"(.*)></div>~Uis', '<img$1src="$2/$3"$4>', $page->body);
$page->body = preg_replace('~<div class="col-sm-6 mb">.*<div class="zooming2-title">.*</div>.*<img(.*)src="(.*)/thumbs/400x300cp/(.*)"(.*)></div>~Uis', '<img$1src="$2/$3"$4>', $page->body);
// Связанные товары
if (is_array($this->request->post('related_products'))) {
foreach ($this->request->post('related_products') as $p) {
$rp[$p]->related_id = $p;
$rp[$p]->type = 'product';
}
$related_objects = $rp;
}
// Связанные статьи
if (is_array($this->request->post('related_pages'))) {
foreach ($this->request->post('related_pages') as $p) {
$rp[$p]->related_id = $p;
$rp[$p]->type = 'page';
}
$related_objects = $rp;
}
if (is_array($this->request->post('related_articles'))) {
foreach ($this->request->post('related_articles') as $p) {
$rp[$p]->related_id = $p;
$rp[$p]->type = 'article';
}
$related_objects = $rp;
}
## Не допустить одинаковые URL разделов.
if (($p = $this->services->get($page->url)) && $p->id != $page->id) {
$this->design->assign('message_error', 'url_exists');
} else {
// url брендовых страниц
/*if(!empty($db_page->brand_id) && ($brand = $this->services->get_brand($db_page->brand_id))) {
$page->url = $brand->url;
}*/
if (empty($page->id)) {
$page->id = $this->pages->add_page($page);
$this->services->set_visible($page->id, $page->visible);
$this->services->fix_positions();
$page = $this->services->get($page->id);
$this->design->assign('message_success', 'added');
} else {
$this->services->update($page->id, $page);
$page = $this->services->get($page->id);
$this->design->assign('message_success', 'updated');
}
// Удаление изображения
if ($this->request->post('delete_image')) {
$this->pages->delete_image($page->id);
}
// Загрузка изображения
$image = $this->request->files('image');
if (!empty($image['name']) && in_array(strtolower(pathinfo($image['name'], PATHINFO_EXTENSION)), $this->allowed_image_extentions)) {
if ($image_name = $this->image->upload_image($image['tmp_name'], $image['name'])) {
$this->pages->delete_image($page->id);
$this->pages->update_page($page->id, array('image' => $image_name));
$page->image = $image_name;
} else {
$this->design->assign('error', 'error uploading image');
}
}
}
// Связанные объекты
$query = $this->db->placehold('DELETE FROM __pages_objects WHERE page_id=?', $page->id);
$this->db->query($query);
if (is_array($related_objects)) {
$pos = 0;
foreach ($related_objects as $i => $related_object)
$this->pages->add_related_object($page->id, $related_object->related_id, $related_object->type);
}
//страница услуги и услуга не брендовая
if (intval($page->menu_id) === $this->services->menu_id && !$page->brand_id) {
// создаём или обновляем её брендовые страницы
$this->services->create_brands_pages($page->id, $this->request->post('brands'));
}
} else {
$id = $this->request->get('id', 'integer');
if (!empty($id) && !empty($page = $this->services->get($id))) {
} else {
$page = new stdClass();
$page->menu_id = $this->services->menu_id;
$page->visible = 1;
}
}
$this->design->assign('page', $page);
$this->design->assign('root_url', $this->services->get_root_url());
// Связанные объекты
$related_objects = $this->pages->get_related_objects(array('id' => $page->id));
if (!empty($related_objects)) {
$r_products = array();
$r_pages = array();
$r_articles = array();
foreach ($related_objects as &$r_p)
if ($r_p->type == 'product') $r_products[$r_p->object_id] = &$r_p;
elseif ($r_p->type == 'page') $r_pages[$r_p->object_id] = &$r_p;
elseif ($r_p->type == 'article') $r_articles[$r_p->object_id] = &$r_p;
if (!empty($r_products)) {
$temp_products = $this->products->get_products(array('id' => array_keys($r_products)));
foreach ($temp_products as $temp_product)
$r_products[$temp_product->id] = $temp_product;
}
if (!empty($r_pages)) {
$temp_pages = $this->pages->get_pages(array('id' => array_keys($r_pages)));
foreach ($temp_pages as $temp_page)
$r_pages[$temp_page->id] = $temp_page;
}
if (!empty($r_articles)) {
$temp_pages = $this->articles->get_articles(array('id' => array_keys($r_articles)));
foreach ($temp_pages as $temp_page)
$r_articles[$temp_page->id] = $temp_page;
}
$page->body = preg_replace_callback('~<img.*class=.*zooming2[^>].*>~Uis', array($this, 'resizeBodyImages'), $page->body);
$this->design->assign('related_products', $r_products);
$this->design->assign('related_pages', $r_pages);
$this->design->assign('related_articles', $r_articles);
}
// Меню выбора родительской страницы (услуги)
$select_items = $this->pages->get_select_pages(array('parent' => $this->services->root_id));
$this->design->assign('select_items', $select_items);
//привязанные к услуге брендовые страницы
if (!$page->brand_id) {
$this->design->assign('service_brands', $this->services->get_service_brands($page->id));
}
// все марки
$this->design->assign('brands', $this->services->get_all_brands());
return $this->design->fetch('service.tpl');
}
function resizeBodyImages($m)
{
preg_match('~src=["\'](.*)["\']~Uis', $m[0], $img);
preg_match('~title=["\'](.*)["\']~Uis', $m[0], $title);
preg_match('~alt=["\'](.*)["\']~Uis', $m[0], $alt);
if (empty($img[1])) return $m[0];
$alt = isset($alt[1]) ? $alt[1] : '';
$title = isset($title[1]) ? $title[1] : '';
$src = Img::get(urldecode($img[1]), array('width' => 400, 'height' => 300, 'crop' => true));
$tl = $title ? '<div class="zooming2-title">' . $title . '</div>' : '';
return '<div class="col-sm-6 mb">' . $tl . '<img alt="' . $alt . '" class="zooming2" src="' . $src . '" title="' . $title . '"></div>' . "\n";
}
}

86
simpla/ServicesAdmin.php Normal file
View File

@@ -0,0 +1,86 @@
<?php
require_once('api/Simpla.php');
class ServicesAdmin extends Simpla
{
public function fetch()
{
if ($this->request->method('post')) {
$ids = $this->request->post('check');
if (is_array($ids)) {
// Действия с выбранными
switch ($this->request->post('action')) {
case 'disable':
foreach ($ids as $id)
$this->services->set_visible($id, 0);
break;
case 'enable':
foreach ($ids as $id)
$this->services->set_visible($id, 1);
break;
case 'delete':
$this->services->delete($ids);
break;
}
}
}
$filters = array();
// фильтры
$filter = $this->request->get('filter', 'string');
if (!empty($filter) && in_array($filter, array('disabled', 'enabled'))) {
$filters['visible'] = intval($filter === 'enabled');
$this->design->assign('filter', $filter);
} elseif('branded' === $filter) {
$filters[$filter] = $filter;
$this->design->assign('filter', $filter);
} elseif('home' === $filter) {
$filters['show_home'] = 1;
$this->design->assign('filter', $filter);
} elseif('main' === $filter) {
$filters['show_service'] = 1;
$this->design->assign('filter', $filter);
}
if ($brand_id = $this->request->get('brand_id', 'integer')) {
$filters['brand_id'] = $brand_id;
$this->design->assign('brand_id', $brand_id);
}
if ($parent = $this->request->get('parent', 'integer')) {
$filters['parent'] = $parent;
$this->design->assign('parent', $parent);
}
// Поиск
$keyword = $this->request->get('keyword');
if (!empty($keyword) && is_string($keyword)) {
$filters['keyword'] = $keyword;
$this->design->assign('keyword', $keyword);
}
// сортировка
$sort_order = $this->request->get('sort', 'string');
$filters['order'] = empty($sort_order) ? 'header' : $sort_order;
// постраничная навигация
$filters['page'] = max(1, $this->request->get('page', 'integer'));
$filters['limit'] = ($this->request->get('page') === 'all') ? 1000 : 20;
$services_count = $this->services->count($filters);
$services = $this->services->all($filters, true);
$this->design->assign('pages_count', ceil($services_count / $filters['limit']));
$this->design->assign('current_page', $filters['page']);
$this->design->assign('sort', $filters['order']);
$this->design->assign('services', $services);
$this->design->assign('services_count', $services_count);
$this->design->assign('brands', $this->services->get_all_brands());
$this->design->assign('tree', $this->services->get_tree());
$this->design->assign('root_url', $this->services->get_root_url());
return $this->design->fetch('services.tpl');
}
}

View File

@@ -0,0 +1,41 @@
<?php
require_once('api/Simpla.php');
class ServicesMenuAdmin extends Simpla
{
function fetch()
{
if ($this->request->method('post')) {
$ids = $this->request->post('check');
if (is_array($ids)) {
// Действия с выбранными
switch ($this->request->post('action')) {
case 'disable':
foreach ($ids as $id)
$this->services->set_visible($id, 0);
break;
case 'enable':
foreach ($ids as $id)
$this->services->set_visible($id,1);
break;
case 'delete':
$this->services->delete($ids, true);
break;
}
}
// Сортировка
$positions = $this->request->post('positions');
$ids = array_keys($positions);
sort($positions);
foreach ($positions as $i => $position)
$this->services->update($ids[$i], array('position' => $position));
}
$this->design->assign('services', $this->services->get_tree());
$this->design->assign('root_url', $this->services->get_root_url());
return $this->design->fetch('services_menu.tpl');
}
}

107
simpla/SettingsAdmin.php Normal file
View File

@@ -0,0 +1,107 @@
<?PHP
require_once('api/Simpla.php');
class SettingsAdmin extends Simpla
{
private $allowed_image_extentions = array('png', 'gif', 'jpg', 'jpeg', 'ico');
public function fetch()
{
$this->passwd_file = $this->config->root_dir.'/simpla/.passwd';
$this->htaccess_file = $this->config->root_dir.'/simpla/.htaccess';
$managers = $this->managers->get_managers();
$this->design->assign('managers', $managers);
if($this->request->method('POST'))
{
$this->settings->site_name = $this->request->post('site_name');
$this->settings->company_name = $this->request->post('company_name');
$this->settings->date_format = $this->request->post('date_format');
$this->settings->admin_email = $this->request->post('admin_email');
$this->settings->order_email = $this->request->post('order_email');
$this->settings->comment_email = $this->request->post('comment_email');
$this->settings->notify_from_email = $this->request->post('notify_from_email');
$this->settings->form_email = $this->request->post('form_email');
$this->settings->form_prefix = $this->request->post('form_prefix');
$this->settings->form_sent = $this->request->post('form_sent');
$this->settings->form_fail = $this->request->post('form_fail');
$this->settings->decimals_point = $this->request->post('decimals_point');
$this->settings->thousands_separator = $this->request->post('thousands_separator');
$this->settings->products_num = $this->request->post('products_num');
$this->settings->products_num_admin = $this->request->post('products_num_admin');
$this->settings->max_order_amount = $this->request->post('max_order_amount');
$this->settings->units = $this->request->post('units');
// Простые звонки
$this->settings->pz_server = $this->request->post('pz_server');
$this->settings->pz_password = $this->request->post('pz_password');
$this->settings->pz_phones = $this->request->post('pz_phones');
// точка отправления ЕМС
$this->settings->emsfrom = $this->request->post('emsfrom');
$this->settings->emstax = $this->request->post('emstax', 'boolean');
if(!$this->settings->emstax)
$this->settings->emstax = 0;
//print_r($this->settings);
// Водяной знак
$clear_image_cache = false;
$watermark = $this->request->files('watermark_file', 'tmp_name');
if(!empty($watermark) && in_array(pathinfo($this->request->files('watermark_file', 'name'), PATHINFO_EXTENSION), $this->allowed_image_extentions))
{
if(@move_uploaded_file($watermark, $this->config->root_dir.$this->config->watermark_file))
$clear_image_cache = true;
else
$this->design->assign('message_error', 'watermark_is_not_writable');
}
if($this->settings->watermark_offset_x != $this->request->post('watermark_offset_x'))
{
$this->settings->watermark_offset_x = $this->request->post('watermark_offset_x');
$clear_image_cache = true;
}
if($this->settings->watermark_offset_y != $this->request->post('watermark_offset_y'))
{
$this->settings->watermark_offset_y = $this->request->post('watermark_offset_y');
$clear_image_cache = true;
}
if($this->settings->watermark_transparency != $this->request->post('watermark_transparency'))
{
$this->settings->watermark_transparency = $this->request->post('watermark_transparency');
$clear_image_cache = true;
}
if($this->settings->images_sharpen != $this->request->post('images_sharpen'))
{
$this->settings->images_sharpen = $this->request->post('images_sharpen');
$clear_image_cache = true;
}
// Удаление заресайзеных изображений
if($clear_image_cache)
{
$dir = $this->config->resized_images_dir;
if($handle = opendir($dir))
{
while(false !== ($file = readdir($handle)))
{
if($file != "." && $file != "..")
{
@unlink($dir."/".$file);
}
}
closedir($handle);
}
}
$this->design->assign('message_success', 'saved');
}
$this->design->assign('cities', $this->cart->getCity2());
return $this->design->fetch('settings.tpl');
}
}

71
simpla/SharesAdmin.php Normal file
View File

@@ -0,0 +1,71 @@
<?php
/**
* Simpla CMS
*
* @copyright 2011 Denis Pikusov
* @link http://simplacms.ru
* @author Denis Pikusov
*
*/
require_once('api/Simpla.php');
class SharesAdmin extends Simpla
{
public function fetch()
{
// Обработка действий
if($this->request->method('post'))
{
// Действия с выбранными
$ids = $this->request->post('check');
if(is_array($ids))
switch($this->request->post('action'))
{
case 'disable':
{
$this->blog->update_post($ids, array('visible'=>0));
break;
}
case 'enable':
{
$this->blog->update_post($ids, array('visible'=>1));
break;
}
case 'delete':
{
foreach($ids as $id)
$this->blog->delete_post($id);
break;
}
}
}
$filter = array();
$filter['page'] = max(1, $this->request->get('page', 'integer'));
$filter['limit'] = 20;
// Поиск
$keyword = $this->request->get('keyword', 'string');
if(!empty($keyword))
{
$filter['keyword'] = $keyword;
$this->design->assign('keyword', $keyword);
}
$posts_count = $this->blog->count_posts($filter);
// Показать все страницы сразу
if($this->request->get('page') == 'all')
$filter['limit'] = $posts_count;
$posts = $this->blog->get_posts($filter);
$this->design->assign('posts_count', $posts_count);
$this->design->assign('pages_count', ceil($posts_count/$filter['limit']));
$this->design->assign('current_page', $filter['page']);
$this->design->assign('posts', $posts);
return $this->design->fetch('blog.tpl');
}
}

16
simpla/StatsAdmin.php Normal file
View File

@@ -0,0 +1,16 @@
<?PHP
require_once('api/Simpla.php');
############################################
# Class goodCategories displays a list of products categories
############################################
class StatsAdmin extends Simpla
{
public function fetch()
{
return $this->design->fetch('stats.tpl');
}
}

76
simpla/StylesAdmin.php Normal file
View File

@@ -0,0 +1,76 @@
<?PHP
require_once('api/Simpla.php');
class StylesAdmin extends Simpla
{
public function fetch()
{
$styles_dir = 'design/'.$this->settings->theme.'/css/';
$styles = array();
// Порядок файлов в меню
$sort = array('style.css', 'reset.css');
// Чтаем все css-файлы
if($handle = opendir($styles_dir)) {
$i = count($sort);
while(false !== ($file = readdir($handle)))
{
if(is_file($styles_dir.$file) && $file[0] != '.' && pathinfo($file, PATHINFO_EXTENSION) == 'css')
{
if(($key = array_search($file, $sort)) !== false)
$styles[$key] = $file;
else
$styles[$i++] = $file;
}
}
closedir($handle);
}
ksort($styles);
// Текущий шаблон
$style_file = $this->request->get('file');
if(!empty($style_file) && pathinfo($style_file, PATHINFO_EXTENSION) != 'css')
exit();
// Если не указан - вспоминаем его из сессии
if(empty($style_file) && isset($_SESSION['last_edited_style']))
$style_file = $_SESSION['last_edited_style'];
// Иначе берем первый файл из списка
elseif(empty($style_file))
$style_file = reset($styles);
// Передаем имя шаблона в дизайн
$this->design->assign('style_file', $style_file);
// Если можем прочитать файл - передаем содержимое в дизайн
if(is_readable($styles_dir.$style_file))
{
$style_content = file_get_contents($styles_dir.$style_file);
$this->design->assign('style_content', $style_content);
}
// Если нет прав на запись - передаем в дизайн предупреждение
if(!empty($style_file) && !is_writable($styles_dir.$style_file) && !is_file($styles_dir.'../locked'))
{
$this->design->assign('message_error', 'permissions');
}
elseif(is_file($styles_dir.'../locked'))
{
$this->design->assign('message_error', 'theme_locked');
}
else
{
// Запоминаем в сессии имя редактируемого шаблона
$_SESSION['last_edited_style'] = $style_file;
}
$this->design->assign('theme', $this->settings->theme);
$this->design->assign('styles', $styles);
return $this->design->fetch('styles.tpl');
}
}

76
simpla/TemplatesAdmin.php Normal file
View File

@@ -0,0 +1,76 @@
<?PHP
require_once('api/Simpla.php');
class TemplatesAdmin extends Simpla
{
public function fetch()
{
$templates_dir = 'design/'.$this->settings->theme.'/html/';
$templates = array();
// Порядок файлов в меню
$sort = array('index.tpl', 'page.tpl', 'products.tpl', 'main.tpl', 'product.tpl', 'blog.tpl', 'post.tpl', 'cart.tpl', 'cart_informer.tpl', 'order.tpl', 'login.tpl', 'register.tpl', 'user.tpl', 'feedback.tpl', 'password_remind.tpl', 'email_order.tpl', 'email_password_remind.tpl', 'pagination.tpl');
// Чтаем все tpl-файлы
if($handle = opendir($templates_dir)) {
$i = count($sort);
while(false !== ($file = readdir($handle)))
{
if(is_file($templates_dir.$file) && $file[0] != '.' && pathinfo($file, PATHINFO_EXTENSION) == 'tpl')
{
if(($key = array_search($file, $sort)) !== false)
$templates[$key] = $file;
else
$templates[$i++] = $file;
}
}
closedir($handle);
ksort($templates);
}
// Текущий шаблон
$template_file = $this->request->get('file');
if(!empty($template_file) && pathinfo($template_file, PATHINFO_EXTENSION) != 'tpl')
exit();
// Если не указан - вспоминаем его из сессии
if(empty($template_file) && isset($_SESSION['last_edited_template']))
$template_file = $_SESSION['last_edited_template'];
// Иначе берем первый файл из списка
elseif(empty($template_file))
$template_file = reset($templates);
// Передаем имя шаблона в дизайн
$this->design->assign('template_file', $template_file);
// Если можем прочитать файл - передаем содержимое в дизайн
if(is_readable($templates_dir.$template_file))
{
$template_content = file_get_contents($templates_dir.$template_file);
$this->design->assign('template_content', $template_content);
}
// Если нет прав на запись - передаем в дизайн предупреждение
if(!empty($template_file) && !is_writable($templates_dir.$template_file) && !is_file($templates_dir.'../locked'))
{
$this->design->assign('message_error', 'permissions');
}
elseif(is_file($templates_dir.'../locked'))
{
$this->design->assign('message_error', 'theme_locked');
}
else
{
// Запоминаем в сессии имя редактируемого шаблона
$_SESSION['last_edited_template'] = $template_file;
}
$this->design->assign('theme', $this->settings->theme);
$this->design->assign('templates', $templates);
return $this->design->fetch('templates.tpl');
}
}

136
simpla/ThemeAdmin.php Normal file
View File

@@ -0,0 +1,136 @@
<?PHP
require_once('api/Simpla.php');
class ThemeAdmin extends Simpla
{
private $themes_dir = 'design/';
private $compiled_dir = 'compiled/';
public function fetch()
{
if($this->request->method('post'))
{
$this->dir_delete($this->compiled_dir, false);
$old_names = $this->request->post('old_name');
$new_names = $this->request->post('new_name');
if(is_array($old_names))
foreach($old_names as $i=>$old_name)
{
$new_name = $new_names[$i];
if(is_writable($this->themes_dir) && is_dir($this->themes_dir.$old_name) && !is_file($this->themes_dir.$new_name)&& !is_dir($this->themes_dir.$new_name))
{
rename($this->themes_dir.$old_name, $this->themes_dir.$new_name);
if($this->settings->theme == $old_name)
$this->settings->theme = $new_name;
}
elseif(is_file($this->themes_dir.$new_name) && $new_name!=$old_name)
$message_error = 'name_exists';
}
$action = $this->request->post('action');
$action_theme = $this->request->post('theme');
switch($this->request->post('action'))
{
case 'set_main_theme':
{
$this->settings->theme = $action_theme;
break;
}
case 'clone_theme':
{
$new_name = $this->settings->theme;
while(is_dir($this->themes_dir.$new_name) || is_file($this->themes_dir.$new_name))
{
if(preg_match('/(.+)_([0-9]+)$/', $new_name, $parts))
$new_name = $parts[1].'_'.($parts[2]+1);
else
$new_name = $new_name.'_1';
}
$this->dir_copy($this->themes_dir.$this->settings->theme, $this->themes_dir.$new_name);
@unlink($this->themes_dir.$new_name.'/locked');
$this->settings->theme = $new_name;
break;
}
case 'delete_theme':
{
$this->dir_delete($this->themes_dir.$action_theme);
if($action_theme == $this->settings->theme)
{
$t = reset($this->get_themes());
$this->settings->theme = $t->name;
}
break;
}
}
}
$themes = $this->get_themes();
// Если нет прав на запись - передаем в дизайн предупреждение
if(!is_writable($this->themes_dir))
{
$this->design->assign('message_error', 'permissions');
}
$current_theme->name = $this->settings->theme;
$current_theme->locked = is_file($this->themes_dir.$current_theme->name.'/locked');
$this->design->assign('theme', $current_theme);
$this->design->assign('themes', $themes);
$this->design->assign('themes_dir', $this->themes_dir);
return $this->design->fetch('theme.tpl');
}
private function dir_copy($src, $dst)
{
if(is_dir($src))
{
mkdir($dst, 0777);
$files = scandir($src);
foreach ($files as $file)
if ($file != "." && $file != "..") $this->dir_copy("$src/$file", "$dst/$file");
}
elseif(file_exists($src))
copy($src, $dst);
@chmod($dts, 0777);
}
private function dir_delete($path, $delete_self = true)
{
if(!$dh = @opendir($path))
return;
while (false !== ($obj = readdir($dh)))
{
if($obj == '.' || $obj == '..')
continue;
if (!@unlink($path . '/' . $obj))
$this->dir_delete($path.'/'.$obj, true);
}
closedir($dh);
if($delete_self)
@rmdir($path);
return;
}
private function get_themes()
{
if($handle = opendir($this->themes_dir)) {
while(false !== ($file = readdir($handle)))
{
if(is_dir($this->themes_dir.'/'.$file) && $file[0] != '.')
{
unset($theme);
$theme->name = $file;
$theme->locked = is_file($this->themes_dir.$file.'/locked');
$themes[] = $theme;
}
}
closedir($handle);
sort($themes);
}
return $themes;
}
}

79
simpla/UserAdmin.php Normal file
View File

@@ -0,0 +1,79 @@
<?PHP
require_once('api/Simpla.php');
class UserAdmin extends Simpla
{
public function fetch()
{
if(!empty($_POST['user_info']))
{
$user->id = $this->request->post('id', 'integer');
$user->enabled = $this->request->post('enabled');
$user->name = $this->request->post('name');
$user->email = $this->request->post('email');
$user->group_id = $this->request->post('group_id');
## Не допустить одинаковые email пользователей.
if(empty($user->name))
{
$this->design->assign('message_error', 'empty_name');
}
elseif(empty($user->email))
{
$this->design->assign('message_error', 'empty_email');
}
elseif(($u = $this->users->get_user($user->email)) && $u->id!=$user->id)
{
$this->design->assign('message_error', 'login_existed');
}
else
{
$user->id = $this->users->update_user($user->id, $user);
$this->design->assign('message_success', 'updated');
$user = $this->users->get_user(intval($user->id));
}
}
elseif($this->request->post('check'))
{
// Действия с выбранными
$ids = $this->request->post('check');
if(is_array($ids))
switch($this->request->post('action'))
{
case 'delete':
{
foreach($ids as $id)
$o = $this->orders->get_order(intval($id));
if($o->status<3)
{
$this->orders->update_order($id, array('status'=>3, 'user_id'=>null));
$this->orders->open($id);
}
else
$this->orders->delete_order($id);
break;
}
}
}
$id = $this->request->get('id', 'integer');
if(!empty($id))
$user = $this->users->get_user(intval($id));
if(!empty($user))
{
$this->design->assign('user', $user);
$orders = $this->orders->get_orders(array('user_id'=>$user->id));
$this->design->assign('orders', $orders);
}
$groups = $this->users->get_groups();
$this->design->assign('groups', $groups);
return $this->design->fetch('user.tpl');
}
}

88
simpla/UsersAdmin.php Normal file
View File

@@ -0,0 +1,88 @@
<?PHP
require_once('api/Simpla.php');
############################################
# Class Properties displays a list of product parameters
############################################
class UsersAdmin extends Simpla
{
function fetch()
{
if($this->request->method('post'))
{
// Действия с выбранными
$ids = $this->request->post('check');
if(is_array($ids))
switch($this->request->post('action'))
{
case 'disable':
{
foreach($ids as $id)
$this->users->update_user($id, array('enabled'=>0));
break;
}
case 'enable':
{
foreach($ids as $id)
$this->users->update_user($id, array('enabled'=>1));
break;
}
case 'delete':
{
foreach($ids as $id)
$this->users->delete_user($id);
break;
}
}
}
foreach($this->users->get_groups() as $g)
$groups[$g->id] = $g;
$group = null;
$filter = array();
$filter['page'] = max(1, $this->request->get('page', 'integer'));
$filter['limit'] = 20;
$group_id = $this->request->get('group_id', 'integer');
if($group_id)
{
$group = $this->users->get_group($group_id);
$filter['group_id'] = $group->id;
}
// Поиск
$keyword = $this->request->get('keyword', 'string');
if(!empty($keyword))
{
$filter['keyword'] = $keyword;
$this->design->assign('keyword', $keyword);
}
// Сортировка пользователей, сохраняем в сессии, чтобы текущая сортировка не сбрасывалась
if($sort = $this->request->get('sort', 'string'))
$_SESSION['users_admin_sort'] = $sort;
if (!empty($_SESSION['users_admin_sort']))
$filter['sort'] = $_SESSION['users_admin_sort'];
else
$filter['sort'] = 'name';
$this->design->assign('sort', $filter['sort']);
$users_count = $this->users->count_users($filter);
// Показать все страницы сразу
if($this->request->get('page') == 'all')
$filter['limit'] = $users_count;
$users = $this->users->get_users($filter);
$this->design->assign('pages_count', ceil($users_count/$filter['limit']));
$this->design->assign('current_page', $filter['page']);
$this->design->assign('groups', $groups);
$this->design->assign('group', $group);
$this->design->assign('users', $users);
$this->design->assign('users_count', $users_count);
return $this->body = $this->design->fetch('users.tpl');
}
}

View File

@@ -0,0 +1,52 @@
<?php
chdir('../..');
require_once('api/Simpla.php');
$simpla = new Simpla();
$limit = 100;
if(!$simpla->managers->access('orders'))
return false;
$keyword = $simpla->request->get('query', 'string');
$simpla->db->query('SELECT p.id, p.name, i.filename as image FROM __products p
LEFT JOIN __images i ON i.product_id=p.id AND i.position=(SELECT MIN(position) FROM __images WHERE product_id=p.id LIMIT 1)
LEFT JOIN __variants pv ON pv.product_id=p.id AND (pv.stock IS NULL OR pv.stock>0) AND pv.price>0
WHERE p.name LIKE "%'.mysql_real_escape_string($keyword).'%"
ORDER BY p.name LIMIT ?', $limit);
$products = array();
foreach($simpla->db->results() as $product)
$products[$product->id] = $product;
$simpla->db->query('SELECT v.id, v.name, v.price, IFNULL(v.stock, ?) as stock, (v.stock IS NULL) as infinity, v.product_id FROM __variants v WHERE v.product_id in(?@) AND (v.stock IS NULL OR v.stock>0) AND v.price>0 ORDER BY v.position', $simpla->settings->max_order_amount, array_keys($products));
$variants = $simpla->db->results();
foreach($variants as $variant)
if(isset($products[$variant->product_id]))
$products[$variant->product_id]->variants[] = $variant;
foreach($products as $product)
{
if(!empty($product->variants))
{
if(!empty($product->image))
{
$product->image = $simpla->design->resize_modifier($product->image, 35, 35);
$products_names[] = $product->name;
}
else
$products_names[] = $product->name;
$products_data[] = $product;
}
}
$res->query = $keyword;
$res->suggestions = $products_names;
$res->data = $products_data;
header("Content-type: application/json; charset=UTF-8");
header("Cache-Control: must-revalidate");
header("Pragma: no-cache");
header("Expires: -1");
print json_encode($res);

186
simpla/ajax/export.php Normal file
View File

@@ -0,0 +1,186 @@
<?php
chdir('../..');
require_once('api/Simpla.php');
class ExportAjax extends Simpla
{
private $columns_names = array(
'category'=> 'Êàòåãîðèÿ',
'name'=> 'Òîâàð',
'price'=> 'Öåíà',
'url'=> 'Àäðåñ',
'visible'=> 'Âèäèì',
'featured'=> 'Ðåêîìåíäóåìûé',
'brand'=> 'Áðåíä',
'variant'=> 'Âàðèàíò',
'compare_price'=> 'Ñòàðàÿ öåíà',
'sku'=> 'Àðòèêóë',
'stock'=> 'Ñêëàä',
'meta_title'=> 'Çàãîëîâîê ñòðàíèöû',
'meta_keywords'=> 'Êëþ÷åâûå ñëîâà',
'meta_description'=> 'Îïèñàíèå ñòðàíèöû',
'annotation'=> 'Àííîòàöèÿ',
'body'=> 'Îïèñàíèå',
'images'=> 'Èçîáðàæåíèÿ'
);
private $column_delimiter = ';';
private $subcategory_delimiter = '/';
private $products_count = 5;
private $export_files_dir = 'simpla/files/export/';
private $filename = 'export.csv';
public function fetch()
{
if(!$this->managers->access('export'))
return false;
// Ýêñåëü êóøàåò òîëüêî 1251
setlocale(LC_ALL, 'ru_RU.1251');
$this->db->query('SET NAMES cp1251');
// Ñòðàíèöà, êîòîðóþ ýêñïîðòèðóåì
$page = $this->request->get('page');
if(empty($page) || $page==1)
{
$page = 1;
// Åñëè íà÷àëè ñíà÷àëà - óäàëèì ñòàðûé ôàéë ýêñïîðòà
if(is_writable($this->export_files_dir.$this->filename))
unlink($this->export_files_dir.$this->filename);
}
// Îòêðûâàåì ôàéë ýêñïîðòà íà äîáàâëåíèå
$f = fopen($this->export_files_dir.$this->filename, 'ab');
// Äîáàâèì â ñïèñîê êîëîíîê ñâîéñòâà òîâàðîâ
$features = $this->features->get_features();
foreach($features as $feature)
$this->columns_names[$feature->name] = $feature->name;
// Åñëè íà÷àëè ñíà÷àëà - äîáàâèì â ïåðâóþ ñòðîêó íàçâàíèÿ êîëîíîê
if($page == 1)
{
fputcsv($f, $this->columns_names, $this->column_delimiter);
}
// Âñå òîâàðû
$products = array();
foreach($this->products->get_products(array('page'=>$page, 'limit'=>$this->products_count)) as $p)
{
$products[$p->id] = (array)$p;
// Ñâîéñòâà òîâàðîâ
$options = $this->features->get_product_options($p->id);
foreach($options as $option)
{
if(!isset($products[$option->product_id][$option->name]))
$products[$option->product_id][$option->name] = $option->value;
}
}
if(empty($products))
return false;
// Êàòåãîðèè òîâàðîâ
foreach($products as $p_id=>&$product)
{
$categories = array();
$cats = $this->categories->get_product_categories($p_id);
foreach($cats as $category)
{
$path = array();
$cat = $this->categories->get_category((int)$category->category_id);
if(!empty($cat))
{
// Âû÷èñëÿåì ñîñòàâëÿþùèå êàòåãîðèè
foreach($cat->path as $p)
$path[] = str_replace($this->subcategory_delimiter, '\\'.$this->subcategory_delimiter, $p->name);
// Äîáàâëÿåì êàòåãîðèþ ê òîâàðó
$categories[] = implode('/', $path);
}
}
$product['category'] = implode(', ', $categories);
}
// Èçîáðàæåíèÿ òîâàðîâ
$images = $this->products->get_images(array('product_id'=>array_keys($products)));
foreach($images as $image)
{
// Äîáàâëÿåì èçîáðàæåíèÿ ê òîâàðó ÷åçåð çàïÿòóþ
if(empty($products[$image->product_id]['images']))
$products[$image->product_id]['images'] = $image->filename;
else
$products[$image->product_id]['images'] .= ', '.$image->filename;
}
$variants = $this->variants->get_variants(array('product_id'=>array_keys($products)));
foreach($variants as $variant)
{
if(isset($products[$variant->product_id]))
{
$v = array();
$v['variant'] = $variant->name;
$v['price'] = $variant->price;
$v['compare_price'] = $variant->compare_price;
$v['sku'] = $variant->sku;
$v['stock'] = $variant->stock;
if($variant->infinity)
$v['stock'] = '';
$products[$variant->product_id]['variants'][] = $v;
}
}
foreach($products as &$product)
{
$variants = $product['variants'];
unset($product['variants']);
if(isset($variants))
foreach($variants as $variant)
{
$result = array();
$result = $product;
foreach($variant as $name=>$value)
$result[$name]=$value;
foreach($this->columns_names as $internal_name=>$column_name)
{
if(isset($result[$internal_name]))
$res[$internal_name] = $result[$internal_name];
else
$res[$internal_name] = '';
}
fputcsv($f, $res, $this->column_delimiter);
}
}
$total_products = $this->products->count_products();
if($this->products_count*$page < $total_products)
return array('end'=>false, 'page'=>$page, 'totalpages'=>$total_products/$this->products_count);
else
return array('end'=>true, 'page'=>$page, 'totalpages'=>$total_products/$this->products_count);
fclose($f);
}
}
$export_ajax = new ExportAjax();
$data = $export_ajax->fetch();
if($data)
{
header("Content-type: application/json; charset=utf-8");
header("Cache-Control: must-revalidate");
header("Pragma: no-cache");
header("Expires: -1");
$json = json_encode($data);
print $json;
}

View File

@@ -0,0 +1,89 @@
<?php
chdir('../..');
require_once('api/Simpla.php');
class ExportAjax extends Simpla
{
private $columns_names = array(
'name'=> 'Èìÿ',
'email'=> 'Email',
'group_name'=> 'Ãðóïïà',
'discount'=> 'Ñêèäêà',
'enabled'=> 'Àêòèâåí',
'created'=> 'Äàòà',
'last_ip'=> 'Ïîñëåäíèé IP'
);
private $column_delimiter = ';';
private $users_count = 5;
private $export_files_dir = 'simpla/files/export_users/';
private $filename = 'users.csv';
public function fetch()
{
if(!$this->managers->access('users'))
return false;
// Ýêñåëü êóøàåò òîëüêî 1251
setlocale(LC_ALL, 'ru_RU.1251');
$this->db->query('SET NAMES cp1251');
// Ñòðàíèöà, êîòîðóþ ýêñïîðòèðóåì
$page = $this->request->get('page');
if(empty($page) || $page==1)
{
$page = 1;
// Åñëè íà÷àëè ñíà÷àëà - óäàëèì ñòàðûé ôàéë ýêñïîðòà
if(is_writable($this->export_files_dir.$this->filename))
unlink($this->export_files_dir.$this->filename);
}
// Îòêðûâàåì ôàéë ýêñïîðòà íà äîáàâëåíèå
$f = fopen($this->export_files_dir.$this->filename, 'ab');
// Åñëè íà÷àëè ñíà÷àëà - äîáàâèì â ïåðâóþ ñòðîêó íàçâàíèÿ êîëîíîê
if($page == 1)
{
fputcsv($f, $this->columns_names, $this->column_delimiter);
}
$filter = array();
$filter['page'] = $page;
$filter['limit'] = $this->users_count;
if($this->request->get('group_id'))
$filter['group_id'] = intval($this->request->get('group_id'));
$filter['sort'] = $this->request->get('sort');
$filter['keyword'] = $this->request->get('keyword');
// Âûáèðàåì ïîëüçîâàòåëåé
$users = array();
foreach($this->users->get_users($filter) as $u)
{
$str = array();
foreach($this->columns_names as $n=>$c)
$str[] = $u->$n;
fputcsv($f, $str, $this->column_delimiter);
}
$total_users = $this->users->count_users();
if($this->users_count*$page < $total_users)
return array('end'=>false, 'page'=>$page, 'totalpages'=>$total_users/$this->users_count);
else
return array('end'=>true, 'page'=>$page, 'totalpages'=>$total_users/$this->users_count);
fclose($f);
}
}
$export_ajax = new ExportAjax();
$json = json_encode($export_ajax->fetch());
header("Content-type: application/json; charset=utf-8");
header("Cache-Control: must-revalidate");
header("Pragma: no-cache");
header("Expires: -1");
print $json;

38
simpla/ajax/file.php Normal file
View File

@@ -0,0 +1,38 @@
<?php
chdir('../..');
require_once('api/Simpla.php');
$simpla = new Simpla();
if(isset($_POST['action']) && $_POST['action'] == 'remove'){
$simpla->db->query("DELETE FROM __article_photo WHERE id=" . (int)$_POST['id']);
die;
}
if(isset($_POST['action']) && $_POST['action'] == 'reorder'){
foreach($_POST['ids'] as $pos => $id){
$simpla->db->query("UPDATE __article_photo SET position='$pos' WHERE id='" . (int)$id ."' " );
}
die;
}
$ext = mb_strtolower(substr(strrchr($_FILES['file']['name'], '.'), 1), 'UTF-8');
$name = $_POST['article_id'] . '_' . md5( uniqid( $_POST['article_id'] . rand(1, 10000), true) ) . '.' . $ext;
move_uploaded_file($_FILES['file']['tmp_name'], $_SERVER['DOCUMENT_ROOT'] . '/files/article_photo/' . $name);
$simpla->db->query("INSERT INTO __article_photo SET article_id='" . (int)$_POST['article_id'] ."', img='$name', position=999 " );
echo $simpla->db->insert_id();
//print_r($_POST); print_r($_FILES);
//echo 3;
//echo json_encode(array('id'=>44, 'img'=>'test'));

View File

@@ -0,0 +1,38 @@
<?php
chdir('../..');
require_once('api/Simpla.php');
$simpla = new Simpla();
if(isset($_POST['action']) && $_POST['action'] == 'remove'){
$simpla->db->query("DELETE FROM __action_photo WHERE id=" . (int)$_POST['id']);
die;
}
if(isset($_POST['action']) && $_POST['action'] == 'reorder'){
foreach($_POST['ids'] as $pos => $id){
$simpla->db->query("UPDATE __action_photo SET position='$pos' WHERE id='" . (int)$id ."' " );
}
die;
}
$ext = mb_strtolower(substr(strrchr($_FILES['file']['name'], '.'), 1), 'UTF-8');
$name = $_POST['article_id'] . '_' . md5( uniqid( $_POST['article_id'] . rand(1, 10000), true) ) . '.' . $ext;
move_uploaded_file($_FILES['file']['tmp_name'], $_SERVER['DOCUMENT_ROOT'] . '/files/post/' . $name);
$simpla->db->query("INSERT INTO __action_photo SET action_id='" . (int)$_POST['article_id'] ."', img='$name', position=999 " );
echo $simpla->db->insert_id();
//print_r($_POST); print_r($_FILES);
//echo 3;
//echo json_encode(array('id'=>44, 'img'=>'test'));

View File

@@ -0,0 +1,46 @@
<?php
$use_curl = true; // Использовать CURL
$keyword = $_GET['keyword'];
$keyword = str_replace(' ', '+', $keyword);
$start=0;
if(isset($_GET['start']))
$start = intval($_GET['start']);
$url = 'http://ajax.googleapis.com/ajax/services/search/images?v=1.0&q='.urlencode($keyword).'&start='.$start.'&rsz=8';
if($use_curl && function_exists('curl_init'))
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_REFERER, 'http://google.com');
curl_setopt($ch, CURLOPT_USERAGENT, "Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.9.168 Version/11.51");
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
// Для использования прокси используйте строки:
//curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
//curl_setopt($ch, CURLOPT_PROXY, '88.85.108.16:8080');
//curl_setopt($ch, CURLOPT_PROXYUSERPWD, 'user:password');
$page = curl_exec($ch);
curl_close($ch);
}
else
{
$page = file_get_contents($url);
}
$data = json_decode($page);
$images = array();
if($data)
foreach ($data->responseData->results as $result)
$images[] = urldecode(str_replace('%2520', '%20', $result->url));
header("Content-type: application/json; charset=UTF-8");
header("Cache-Control: must-revalidate");
header("Pragma: no-cache");
header("Expires: -1");
print(json_encode($images));

101
simpla/ajax/get_info.php Normal file
View File

@@ -0,0 +1,101 @@
<?php
$use_curl = true; // Использовать CURL
// Ключевое слово для поиска
$keyword = $_GET['keyword'];
$keyword = str_replace(' ', '+', $keyword);
// Адрес страницы с результатами поиска
$url = "http://market.yandex.ru/search.xml?text=$keyword&nopreciser=1";
// Выбираем результаты поиска
$page = get_page($url);
// Находим ссылку на описание товара
if(preg_match_all('/<h3 class="b-offers__title"><a href="(.*?)" class="b-offers__name">/ui', $page, $matches))
$product_url = 'http://market.yandex.ru'.reset($matches[1]);
else
return false;
$page = get_page($product_url);
if(preg_match_all('/<ul class="b-vlist b-vlist_type_mdash b-vlist_type_friendly">(.*?)/ui', $page, $matches))
{
// Описание товара
$description = '<ul>'.reset($matches[1]).'</ul>';
$result->description = $description;
// Страница характеристик
if(preg_match_all('/<p class="b-model-friendly__title"><a href="(.*?)">все характеристики<\/a><\/p>/ui', $page, $matches))
{
$options_url = 'http://market.yandex.ru'.reset($matches[1]);
$options_page = get_page($options_url);
preg_match_all('/<th class="b-properties__label b-properties__label-title"><span>(.*?)<\/span><\/th><td class="b-properties__value">(.*?)<\/td>/ui', $options_page, $matches, PREG_SET_ORDER);
$options = array();
foreach($matches as $m)
{
$option = null;
$option->name = $m[1];
$option->value = $m[2];
$options[] = $option;
}
$result->options = $options;
}
else
return false;
}
else
return false;
header("Content-type: application/json; charset=UTF-8");
header("Cache-Control: must-revalidate");
header("Pragma: no-cache");
header("Expires: -1");
print(json_encode($result));
function get_page($url, $use_curl=true)
{
if($use_curl && function_exists('curl_init'))
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_REFERER, 'http://google.com');
curl_setopt($ch, CURLOPT_USERAGENT, "Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.9.168 Version/11.51");
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// Для использования прокси используйте строки:
//curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
//curl_setopt($ch, CURLOPT_PROXY, '88.85.108.16:8080');
//curl_setopt($ch, CURLOPT_PROXYUSERPWD, 'user:password');
// Яндекс может нас отправить в редирект, так что нужно следовать за редиректом
do{
curl_setopt($ch, CURLOPT_URL, $url);
$header = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if($code == 301 || $code == 302)
{
preg_match('/Location:(.*?)\n/', $header, $matches);
$url = trim(array_pop($matches));
}
else
$code = 0;
}while($code);
$page = curl_exec($ch);
curl_close($ch);
}
else
{
$page = file_get_contents($url);
}
return $page;
}

View File

@@ -0,0 +1,14 @@
<?php
chdir('../..');
require_once('api/Simpla.php');
$simpla = new Simpla();
$limit = 100;
$results = $simpla->services->get_brands_pages($simpla->request->get('id', 'integer'));
header("Content-type: application/json; charset=UTF-8");
header("Cache-Control: must-revalidate");
header("Pragma: no-cache");
header("Expires: -1");
print json_encode($results);

396
simpla/ajax/import.php Normal file
View File

@@ -0,0 +1,396 @@
<?php
chdir('../..');
require_once('api/Simpla.php');
class ImportAjax extends Simpla
{
// Соответствие полей в базе и имён колонок в файле
private $columns_names = array(
'name'=> array('product', 'name', 'товар', 'название', 'наименование'),
'url'=> array('url', 'адрес'),
'visible'=> array('visible', 'published', 'видим'),
'featured'=> array('featured', 'hit', 'хит', 'рекомендуемый'),
'category'=> array('category', 'категория'),
'brand'=> array('brand', 'бренд'),
'variant'=> array('variant', 'вариант'),
'price'=> array('price', 'цена'),
'compare_price'=> array('compare price', 'старая цена'),
'sku'=> array('sku', 'артикул'),
'stock'=> array('stock', 'склад', 'на складе'),
'meta_title'=> array('meta title', 'заголовок страницы'),
'meta_keywords'=> array('meta keywords', 'ключевые слова'),
'meta_description'=> array('meta description', 'описание страницы'),
'annotation'=> array('annotation', 'аннотация', 'краткое описание'),
'description'=> array('description', 'описание'),
'images'=> array('images', 'изображения')
);
// Соответствие имени колонки и поля в базе
private $internal_columns_names = array();
private $import_files_dir = 'simpla/files/import/'; // Временная папка
private $import_file = 'import.csv'; // Временный файл
private $category_delimiter = ','; // Разделитель каегорий в файле
private $subcategory_delimiter = '/'; // Разделитель подкаегорий в файле
private $column_delimiter = ';';
private $products_count = 10;
private $columns = array();
public function import()
{
if(!$this->managers->access('import'))
return false;
// Для корректной работы установим локаль UTF-8
setlocale(LC_ALL, 'ru_RU.UTF-8');
// Определяем колонки из первой строки файла
$f = fopen($this->import_files_dir.$this->import_file, 'r');
$this->columns = fgetcsv($f, null, $this->column_delimiter);
// Заменяем имена колонок из файла на внутренние имена колонок
foreach($this->columns as &$column)
{
if($internal_name = $this->internal_column_name($column))
{
$this->internal_columns_names[$column] = $internal_name;
$column = $internal_name;
}
}
// Если нет названия товара - не будем импортировать
if(!in_array('name', $this->columns) && !in_array('sku', $this->columns))
return false;
// Переходим на заданную позицию, если импортируем не сначала
if($from = $this->request->get('from'))
fseek($f, $from);
// Массив импортированных товаров
$imported_items = array();
// Проходимся по строкам, пока не конец файла
// или пока не импортировано достаточно строк для одного запроса
for($k=0; !feof($f) && $k<$this->products_count; $k++)
{
// Читаем строку
$line = fgetcsv($f, 0, $this->column_delimiter);
$product = null;
if(is_array($line))
// Проходимся по колонкам строки
foreach($this->columns as $i=>$col)
{
// Создаем массив item[названиеолонки]=значение
if(isset($line[$i]) && !empty($line) && !empty($col))
$product[$col] = $line[$i];
}
// Импортируем этот товар
if($imported_item = $this->import_item($product))
$imported_items[] = $imported_item;
}
/*
if(count($variants_ids)>0)
{
// Для отчета выбираем импортированные товары
$variants = (array)$this->variants->get_variants(array('id'=>$variants_ids));
$products_ids = array();
foreach($variants as $v)
$products_ids[] = $v->product_id;
$products = array();
foreach($this->products->get_products(array('id'=>$products_ids)) as $p)
$products[$p->id] = $p;
foreach($variants as $v)
{
$imported_items[$v->id]->variant_id = $v->id;
$imported_items[$v->id]->product_id = $v->product_id;
$imported_items[$v->id]->variant_name = $v->name;
$imported_items[$v->id]->product_name = $products[$v->product_id]->name;
}
}
else
{
$imported_items = null;
}
*/
// Запоминаем на каком месте закончили импорт
$from = ftell($f);
// И закончили ли полностью весь файл
$result->end = feof($f);
fclose($f);
$size = filesize($this->import_files_dir.$this->import_file);
// Создаем объект результата
$result->from = $from; // На каком месте остановились
$result->totalsize = $size; // Размер всего файла
$result->items = $imported_items; // Импортированные товары
return $result;
}
// Импорт одного товара $item[column_name] = value;
private function import_item($item)
{
// Проверим не пустое ли название и артинкул (должно быть хоть что-то из них)
if(empty($item['name']) && empty($item['sku']))
return false;
// Подготовим товар для добавления в базу
if(isset($item['name']))
$product['name'] = trim($item['name']);
if(isset($item['meta_title']))
$product['meta_title'] = trim($item['meta_title']);
if(isset($item['meta_keywords']))
$product['meta_keywords'] = trim($item['meta_keywords']);
if(isset($item['meta_description']))
$product['meta_description'] = trim($item['meta_description']);
if(isset($item['annotation']))
$product['annotation'] = trim($item['annotation']);
if(isset($item['description']))
$product['body'] = trim($item['description']);
if(isset($item['visible']))
$product['visible'] = intval($item['visible']);
if(isset($item['featured']))
$product['featured'] = intval($item['featured']);
if(isset($item['url']))
$product['url'] = trim($item['url']);
elseif(isset($item['name']))
$product['url'] = $this->translit($item['name']);
// Если задан бренд
if(!empty($item['brand']))
{
$item['brand'] = trim($item['brand']);
// Найдем его по имени
$this->db->query('SELECT id FROM __brands WHERE name=?', $item['brand']);
if(!$product['brand_id'] = $this->db->result('id'))
// Создадим, если не найден
$product['brand_id'] = $this->brands->add_brand(array('name'=>$item['brand'], 'meta_title'=>$item['brand'], 'meta_keywords'=>$item['brand'], 'meta_description'=>$item['brand']));
}
// Если задана категория
$category_id = null;
$categories_ids = array();
if(isset($item['category']))
{
foreach(explode($this->category_delimiter, $item['category']) as $c)
$categories_ids[] = $this->import_category($c);
$category_id = reset($categories_ids);
}
// Подготовим вариант товара
if(isset($item['variant']))
$variant['name'] = trim($item['variant']);
if(isset($item['price']))
$variant['price'] = str_replace(',', '.', trim($item['price']));
if(isset($item['compare_price']))
$variant['compare_price'] = trim($item['compare_price']);
if(isset($item['stock']))
if($item['stock'] == '')
$variant['stock'] = null;
else
$variant['stock'] = trim($item['stock']);
if(isset($item['sku']))
$variant['sku'] = trim($item['sku']);
// Если задан артикул варианта, найдем этот вариант и соответствующий товар
if(!empty($variant['sku']))
{
$this->db->query('SELECT id as variant_id, product_id FROM __variants WHERE sku=? LIMIT 1', $variant['sku']);
$result = $this->db->result();
if($result)
{
// и обновим товар
if(!empty($product))
$this->products->update_product($result->product_id, $product);
// и вариант
if(!empty($variant))
$this->variants->update_variant($result->variant_id, $variant);
$product_id = $result->product_id;
$variant_id = $result->variant_id;
// Обновлен
$imported_item->status = 'updated';
}
}
// Если на прошлом шаге товар не нашелся, и задано хотя бы название товара
if((empty($product_id) || empty($variant_id)) && isset($item['name']))
{
if(!empty($variant['sku']) && empty($variant['name']))
$this->db->query('SELECT v.id as variant_id, p.id as product_id FROM __products p LEFT JOIN __variants v ON v.product_id=p.id WHERE v.sku=? LIMIT 1', $variant['sku']);
elseif(isset($item['variant']))
$this->db->query('SELECT v.id as variant_id, p.id as product_id FROM __products p LEFT JOIN __variants v ON v.product_id=p.id AND v.name=? WHERE p.name=? LIMIT 1', $item['variant'], $item['name']);
else
$this->db->query('SELECT v.id as variant_id, p.id as product_id FROM __products p LEFT JOIN __variants v ON v.product_id=p.id WHERE p.name=? LIMIT 1', $item['name']);
$r = $this->db->result();
if($r)
{
$product_id = $r->product_id;
$variant_id = $r->variant_id;
}
// Если товар найден - обноаляем,
if(!empty($variant_id))
{
$this->variants->update_variant($variant_id, $variant);
$this->products->update_product($product_id, $product);
$imported_item->status = 'updated';
}
// Иначе - добавляем
elseif(empty($variant_id))
{
if(empty($product_id))
$product_id = $this->products->add_product($product);
$variant['product_id'] = $product_id;
$variant_id = $this->variants->add_variant($variant);
$imported_item->status = 'added';
}
}
// Нужно вернуть обновленный товар
$imported_item->variant = $this->variants->get_variant(intval($variant_id));
$imported_item->product = $this->products->get_product(intval($product_id));
// Добавляем категории к товару
if(!empty($categories_ids))
foreach($categories_ids as $c_id)
$this->categories->add_product_category($product_id, $c_id);
// Изображения товаров
if(isset($item['images']))
{
// Изображений может быть несколько, через запятую
$images = explode(',', $item['images']);
foreach($images as $image)
{
$image = trim($image);
if(!empty($image))
{
// Имя файла
$image_filename = pathinfo($image, PATHINFO_BASENAME);
// Добавляем изображение только если такого еще нет в этом товаре
$this->db->query('SELECT filename FROM __images WHERE product_id=? AND (filename=? OR filename=?) LIMIT 1', $product_id, $image_filename, $image);
if(!$this->db->result('filename'))
{
$this->products->add_image($product_id, $image);
}
}
}
}
// Характеристики товаров
foreach($item as $feature_name=>$feature_value)
{
// Если нет такого названия колонки, значит это название свойства
if(!in_array($feature_name, $this->internal_columns_names))
{
// Свойство добавляем только если для товара указана категория
if($category_id)
{
$this->db->query('SELECT f.id FROM __features f WHERE f.name=? LIMIT 1', $feature_name);
if(!$feature_id = $this->db->result('id'))
$feature_id = $this->features->add_feature(array('name'=>$feature_name));
$this->features->add_feature_category($feature_id, $category_id);
$this->features->update_option($product_id, $feature_id, $feature_value);
}
}
}
return $imported_item;
}
// Отдельная функция для импорта категории
private function import_category($category)
{
// Поле "категория" может состоять из нескольких имен, разделенных subcategory_delimiter-ом
// Только неэкранированный subcategory_delimiter может разделять категории
$delimiter = $this->subcategory_delimiter;
$regex = "/\\DELIMITER((?:[^\\\\\DELIMITER]|\\\\.)*)/";
$regex = str_replace('DELIMITER', $delimiter, $regex);
$names = preg_split($regex, $category, 0, PREG_SPLIT_DELIM_CAPTURE);
$id = null;
$parent = 0;
// Для каждой категории
foreach($names as $name)
{
// Заменяем \/ на /
$name = trim(str_replace("\\$delimiter", $delimiter, $name));
if(!empty($name))
{
// Найдем категорию по имени
$this->db->query('SELECT id FROM __categories WHERE name=? AND parent_id=?', $name, $parent);
$id = $this->db->result('id');
// Если не найдена - добавим ее
if(empty($id))
$id = $this->categories->add_category(array('name'=>$name, 'parent_id'=>$parent, 'meta_title'=>$name, 'meta_keywords'=>$name, 'meta_description'=>$name, 'url'=>$this->translit($name)));
$parent = $id;
}
}
return $id;
}
private function translit($text)
{
$ru = explode('-', "А-а-Б-б-В-в-Ґ-ґ-Г-г-Д-д-Е-е-Ё-ё-Є-є-Ж-ж-З-з-И-и-І-і-Ї-ї-Й-й-К-к-Л-л-М-м-Н-н-О-о-П-п-Р-р-С-с-Т-т-У-у-Ф-ф-Х-х-Ц-ц-Ч-ч-Ш-ш-Щ-щ-Ъ-ъ-Ы-ы-Ь-ь-Э-э-Ю-ю-Я-я");
$en = explode('-', "A-a-B-b-V-v-G-g-G-g-D-d-E-e-E-e-E-e-ZH-zh-Z-z-I-i-I-i-I-i-J-j-K-k-L-l-M-m-N-n-O-o-P-p-R-r-S-s-T-t-U-u-F-f-H-h-TS-ts-CH-ch-SH-sh-SCH-sch---Y-y---E-e-YU-yu-YA-ya");
$res = str_replace($ru, $en, $text);
$res = preg_replace("/[\s]+/ui", '-', $res);
$res = preg_replace('/[^\p{L}\p{Nd}\d-]/ui', '', $res);
$res = strtolower($res);
return $res;
}
// Фозвращает внутреннее название колонки по названию колонки в файле
private function internal_column_name($name)
{
$name = trim($name);
$name = str_replace('/', '', $name);
$name = str_replace('\/', '', $name);
foreach($this->columns_names as $i=>$names)
{
foreach($names as $n)
if(!empty($name) && preg_match("/^".preg_quote($name)."$/ui", $n))
return $i;
}
return false;
}
}
$import_ajax = new ImportAjax();
header("Content-type: application/json; charset=UTF-8");
header("Cache-Control: must-revalidate");
header("Pragma: no-cache");
header("Expires: -1");
$json = json_encode($import_ajax->import());
print $json;

View File

@@ -0,0 +1,24 @@
<?php
chdir('../..');
require_once('api/Simpla.php');
$simpla = new Simpla();
$limit = 100;
$keyword = $simpla->request->get('query', 'string');
$feature_id = $simpla->request->get('feature_id', 'string');
$query = $simpla->db->placehold('SELECT DISTINCT po.value FROM __options po
WHERE value LIKE "'.mysql_real_escape_string($keyword).'%" AND feature_id=? ORDER BY po.value LIMIT ?', $feature_id, $limit);
$simpla->db->query($query);
$options = $simpla->db->results('value');
$res->query = $keyword;
$res->suggestions = $options;
header("Content-type: application/json; charset=UTF-8");
header("Cache-Control: must-revalidate");
header("Pragma: no-cache");
header("Expires: -1");
print json_encode($res);

View File

@@ -0,0 +1,36 @@
<?php
session_start();
chdir('../..');
require_once('api/Simpla.php');
$simpla = new Simpla();
if(!$simpla->managers->access('design'))
return false;
// Проверка сессии для защиты от xss
if(!$simpla->request->check_session())
{
trigger_error('Session expired', E_USER_WARNING);
exit();
}
$content = $simpla->request->post('content');
$style = $simpla->request->post('style');
$theme = $simpla->request->post('theme', 'string');
if(pathinfo($style, PATHINFO_EXTENSION) != 'css')
exit();
$file = $simpla->config->root_dir.'design/'.$theme.'/css/'.$style;
if(is_file($file) && is_writable($file) && !is_file($simpla->config->root_dir.'design/'.$theme.'/locked'))
file_put_contents($file, $content);
$result= true;
header("Content-type: application/json; charset=UTF-8");
header("Cache-Control: must-revalidate");
header("Pragma: no-cache");
header("Expires: -1");
$json = json_encode($result);
print $json;

View File

@@ -0,0 +1,36 @@
<?php
session_start();
chdir('../..');
require_once('api/Simpla.php');
$simpla = new Simpla();
if(!$simpla->managers->access('design'))
return false;
// Проверка сессии для защиты от xss
if(!$simpla->request->check_session())
{
trigger_error('Session expired', E_USER_WARNING);
exit();
}
$content = $simpla->request->post('content');
$template = $simpla->request->post('template');
$theme = $simpla->request->post('theme', 'string');
if(pathinfo($template, PATHINFO_EXTENSION) != 'tpl')
exit();
$file = $simpla->config->root_dir.'design/'.$theme.'/html/'.$template;
if(is_file($file) && is_writable($file) && !is_file($simpla->config->root_dir.'design/'.$theme.'/locked'))
file_put_contents($file, $content);
$result= true;
header("Content-type: application/json; charset=UTF-8");
header("Cache-Control: must-revalidate");
header("Pragma: no-cache");
header("Expires: -1");
$json = json_encode($result);
print $json;

View File

@@ -0,0 +1,27 @@
<?php
chdir('../..');
require_once('api/Simpla.php');
$simpla = new Simpla();
$limit = 100;
$keyword = $simpla->request->get('query', 'string');
$simpla->db->query('SELECT id, name FROM __articles
WHERE name LIKE "%'.mysql_real_escape_string($keyword).'%" ORDER BY name LIMIT ?', $limit);
$products = $simpla->db->results();
foreach($products as $product)
{
$products_names[] = $product->name;
$products_data[] = $product;
}
$res->query = $keyword;
$res->suggestions = $products_names;
$res->data = $products_data;
header("Content-type: application/json; charset=UTF-8");
header("Cache-Control: must-revalidate");
header("Pragma: no-cache");
header("Expires: -1");
print json_encode($res);

View File

@@ -0,0 +1,27 @@
<?php
chdir('../..');
require_once('api/Simpla.php');
$simpla = new Simpla();
$limit = 100;
$keyword = $simpla->request->get('query', 'string');
$simpla->db->query('SELECT id, name FROM __marka
WHERE name LIKE "%'.mysql_real_escape_string($keyword).'%" ORDER BY name LIMIT ?', $limit);
$products = $simpla->db->results();
foreach($products as $product)
{
$products_names[] = $product->name;
$products_data[] = $product;
}
$res->query = $keyword;
$res->suggestions = $products_names;
$res->data = $products_data;
header("Content-type: application/json; charset=UTF-8");
header("Cache-Control: must-revalidate");
header("Pragma: no-cache");
header("Expires: -1");
print json_encode($res);

View File

@@ -0,0 +1,41 @@
<?php
chdir('../..');
require_once('api/Simpla.php');
$simpla = new Simpla();
$limit = 100;
$keyword = $simpla->request->get('query', 'string');
$simpla->db->query('SELECT id, name, marka_id FROM __model
WHERE name LIKE "%'.mysql_real_escape_string($keyword).'%" ORDER BY name LIMIT ?', $limit);
$products = $simpla->db->results();
foreach($products as $product)
{
$marka = $simpla->model->getMarka($product->marka_id);
$product->name = $marka ? $marka->name . ' - ' . $product->name : $product->name;
//$products_names[] = $product->name;
$products_data[] = $product;
}
usort($products_data, 'sortNamesUsort');
$products_names = array();
foreach($products_data as $row) $products_names[] = $row->name;
$res->query = $keyword;
$res->suggestions = $products_names;
$res->data = $products_data;
header("Content-type: application/json; charset=UTF-8");
header("Cache-Control: must-revalidate");
header("Pragma: no-cache");
header("Expires: -1");
echo json_encode($res);
function sortNamesUsort($a, $b){
if($a->name < $b->name) return -1;
return $a->name > $b->name ? 1 : 0;
}

View File

@@ -0,0 +1,18 @@
<?php
chdir('../..');
require_once('api/Simpla.php');
$simpla = new Simpla();
$limit = 100;
$keyword = $simpla->request->get('keyword', 'string');
if($simpla->request->get('limit', 'integer'))
$limit = $simpla->request->get('limit', 'integer');
$orders = array_values($simpla->orders->get_orders(array('keyword'=>$keyword, 'limit'=>$limit)));
header("Content-type: application/json; charset=UTF-8");
header("Cache-Control: must-revalidate");
header("Pragma: no-cache");
header("Expires: -1");
print json_encode($orders);

View File

@@ -0,0 +1,27 @@
<?php
chdir('../..');
require_once('api/Simpla.php');
$simpla = new Simpla();
$limit = 100;
$keyword = $simpla->request->get('query', 'string');
$simpla->db->query('SELECT id, name FROM __pages
WHERE name LIKE "%'.mysql_real_escape_string($keyword).'%" AND menu_id=3 ORDER BY name LIMIT ?', $limit);
$products = $simpla->db->results();
foreach($products as $product)
{
$products_names[] = $product->name;
$products_data[] = $product;
}
$res->query = $keyword;
$res->suggestions = $products_names;
$res->data = $products_data;
header("Content-type: application/json; charset=UTF-8");
header("Cache-Control: must-revalidate");
header("Pragma: no-cache");
header("Expires: -1");
print json_encode($res);

View File

@@ -0,0 +1,35 @@
<?php
chdir('../..');
require_once('api/Simpla.php');
$simpla = new Simpla();
$limit = 100;
$keyword = $simpla->request->get('query', 'string');
$simpla->db->query('SELECT p.id, p.name,p.visible, i.filename as image FROM __products p
LEFT JOIN __images i ON i.product_id=p.id AND i.position=(SELECT MIN(position) FROM __images WHERE product_id=p.id LIMIT 1)
WHERE p.name LIKE "%'.mysql_real_escape_string($keyword).'%" ORDER BY p.name LIMIT ?', $limit);
$products = $simpla->db->results();
foreach($products as $product)
{
if($product->visible == 0) continue;
if(!empty($product->image))
{
$product->image = $simpla->design->resize_modifier($product->image, 35, 35);
$products_names[] = $product->name;
}
else
$products_names[] = $product->name;
$products_data[] = $product;
}
$res->query = $keyword;
$res->suggestions = $products_names;
$res->data = $products_data;
header("Content-type: application/json; charset=UTF-8");
header("Cache-Control: must-revalidate");
header("Pragma: no-cache");
header("Expires: -1");
print json_encode($res);

View File

@@ -0,0 +1,63 @@
<?php
function showRes($res)
{
header("Content-type: application/json; charset=UTF-8");
header("Cache-Control: must-revalidate");
header("Pragma: no-cache");
header("Expires: -1");
print json_encode($res);
exit();
}
chdir('../..');
require_once('api/Simpla.php');
$simpla = new Simpla();
$limit = 100;
$keyword = $simpla->request->get('query', 'string');
//function buildFlatServiceTree($serviceId, $main = true)
//{
// global $simpla;
// $simpla->db->query("SELECT * FROM __pages WHERE parent = ? ORDER BY name", $serviceId);
// $services = $simpla->db->results();
// $res = [];
// foreach ($services as $service) {
//// $res = array_merge($res, buildFlatServiceTree($service->id));
// if ($main && $service->show_service != 1) continue;
// $res[] = [
// 'id' => $service->id,
// 'name' => $service->name,
// ];
// }
// return $res;
//}
$simpla->db->query("SELECT * FROM __pages WHERE show_service = 1 ORDER BY name");
$services = $simpla->db->results();
//$services = buildFlatServiceTree(28);
if ($keyword) {
$services = array_filter($services, function ($service) use ($keyword) {
return strpos(mb_strtolower($service->name), mb_strtolower($keyword)) !== false;
});
}
foreach ($services as $service) {
$service_name[] = $service->name;
$services_data[] = $service;
}
$res->query = $keyword;
$res->suggestions = $service_name;
$res->data = $services_data;
showRes($res);

View File

@@ -0,0 +1,25 @@
<?php
chdir('../..');
require_once('api/Simpla.php');
$simpla = new Simpla();
$limit = 100;
$keyword = $simpla->request->get('query', 'string');
$simpla->db->query('SELECT u.id, u.name, u.email FROM __users u WHERE u.name LIKE "%'.mysql_real_escape_string($keyword).'%" OR u.email LIKE "%'.mysql_real_escape_string($keyword).'%"ORDER BY u.name LIMIT ?', $limit);
$users = $simpla->db->results();
foreach($users as $user)
{
$names[] = $user->name." ($user->email)";
$data[] = $user;
}
$res->query = $keyword;
$res->suggestions = $names;
$res->data = $data;
header("Content-type: application/json; charset=UTF-8");
header("Cache-Control: must-revalidate");
header("Pragma: no-cache");
header("Expires: -1");
print json_encode($res);

34
simpla/ajax/stat/stat.php Normal file
View File

@@ -0,0 +1,34 @@
<?php
chdir('../../..');
require_once('api/Simpla.php');
class StatAjax extends Simpla
{
public function fetch()
{
$query = $this->db->placehold('SELECT SUM( o.total_price ) AS total_price, DAY(date) AS day, MONTH(date) as month, YEAR(date) as year FROM __orders o WHERE o.closed AND date > DATE_SUB(NOW(), INTERVAL 1 MONTH) GROUP BY DATE( o.date ) DESC LIMIT 30');
$this->db->query($query);
$data = $this->db->results();
$results = array();
foreach($data as $d)
{
$result['day'] = $d->day;
$result['month'] = $d->month;
$result['year'] = $d->year;
$result['y'] = $d->total_price;
$results[] = $result;
}
return $results;
}
}
$stat_ajax = new StatAjax();
header("Content-type: application/json; charset=utf-8");
header("Cache-Control: must-revalidate");
header("Pragma: no-cache");
header("Expires: -1");
$json = json_encode($stat_ajax->fetch());
print $json;

View File

@@ -0,0 +1,120 @@
<?php
session_start();
chdir('../..');
require_once('api/Simpla.php');
$simpla = new Simpla();
// Проверка сессии для защиты от xss
if(!$simpla->request->check_session())
{
trigger_error('Session expired', E_USER_WARNING);
exit();
}
$id = intval($simpla->request->post('id'));
$object = $simpla->request->post('object');
$values = $simpla->request->post('values');
switch ($object)
{
case 'product':
if($simpla->managers->access('products'))
$result = $simpla->products->update_product($id, $values);
break;
case 'category':
if($simpla->managers->access('categories'))
$result = $simpla->categories->update_category($id, $values);
break;
case 'categoryview':
if($simpla->managers->access('categories'))
$result = $simpla->categories->update_category($id, $values);
break;
case 'article_category':
//if($simpla->managers->access('articles_category'))
$result = $simpla->articles->update_category($id, $values);
break;
case 'banner':
$result = $simpla->banners->update_banner($id, $values);
break;
case 'brands':
$result = $simpla->brands->update_brand($id, $values);
break;
case 'marka':
$result = $simpla->marka->update_brand($id, $values);
break;
case 'model':
$result = $simpla->model->update_model($id, $values);
break;
case 'feature':
if($simpla->managers->access('features'))
$result = $simpla->features->update_feature($id, $values);
break;
case 'page':
if($simpla->managers->access('pages')) {
$action = $simpla->request->post('action','string');
if('move' === $action) {
$result = $simpla->services->move($id, $values);
} elseif('enable' === $action){
$simpla->services->set_visible($id, $values['visible']);
} else
$result = $simpla->pages->update_page($id, $values);
}
break;
case 'blog':
if($simpla->managers->access('blog'))
$result = $simpla->blog->update_post($id, $values);
break;
case 'actions':
if($simpla->managers->access('actions'))
$result = $simpla->actions->update_post($id, $values);
break;
case 'articles':
if($simpla->managers->access('articles'))
$result = $simpla->articles->update_article($id, $values);
break;
case 'delivery':
if($simpla->managers->access('delivery'))
$result = $simpla->delivery->update_delivery($id, $values);
break;
case 'payment':
if($simpla->managers->access('payment'))
$result = $simpla->payment->update_payment_method($id, $values);
break;
case 'currency':
if($simpla->managers->access('currency'))
$result = $simpla->money->update_currency($id, $values);
break;
case 'comment':
if($simpla->managers->access('comments'))
$result = $simpla->comments->update_comment($id, $values);
break;
case 'user':
if($simpla->managers->access('users'))
$result = $simpla->users->update_user($id, $values);
break;
case 'label':
if($simpla->managers->access('labels'))
$result = $simpla->orders->update_label($id, $values);
break;
}
header("Content-type: application/json; charset=UTF-8");
header("Cache-Control: must-revalidate");
header("Pragma: no-cache");
header("Expires: -1");
$json = json_encode($result);
print $json;

37
simpla/ajax/ym.php Normal file
View File

@@ -0,0 +1,37 @@
<?php
chdir('../..');
require_once('api/Simpla.php');
$simpla = new Simpla();
$object = $simpla->request->get('type');
$yms = $simpla->request->post('ym');
//print_r($yms);
$res = array();
switch ($object)
{
case 'prod':
foreach($yms AS $id=>$val)
$result = $simpla->products->update_product($id, array('ym'=>$val));
break;
case 'cat':
foreach($yms AS $id=>$val){
$result = $simpla->categories->update_category($id, array('ym'=>$val));
$results = $simpla->products->get_products(array('category_id'=>$id));
foreach($results AS $p)
$result = $simpla->products->update_product($p->id, array('ym'=>$val));
/*$ids[] = $p->id;
if($val==0)
print_r($ids);*/
}
break;
}
//print_r($yms);
//$res = $yms;
header("Content-type: application/json; charset=UTF-8");
header("Cache-Control: must-revalidate");
header("Pragma: no-cache");
header("Expires: -1");
print json_encode($res);

749
simpla/cml/1c_exchange.php Normal file
View File

@@ -0,0 +1,749 @@
<?php
// Папка для хранения временных файлов синхронизации
$dir = 'simpla/cml/temp/';
// Обновлять все данные при каждой синхронизации
$full_update = true;
// Название параметра товара, используемого как бренд
$brand_option_name = 'Производитель';
$start_time = microtime(true);
$max_exec_time = min(30, @ini_get("max_execution_time"));
if(empty($max_exec_time))
$max_exec_time = 30;
session_start();
chdir('../..');
include('api/Simpla.php');
$simpla = new Simpla();
if($simpla->request->get('type') == 'sale' && $simpla->request->get('mode') == 'checkauth')
{
print "success\n";
print session_name()."\n";
print session_id();
}
if($simpla->request->get('type') == 'sale' && $simpla->request->get('mode') == 'init')
{
$tmp_files = glob($dir.'*.*');
if(is_array($tmp_files))
foreach($tmp_files as $v)
{
//unlink($v);
}
print "zip=no\n";
print "file_limit=1000000\n";
}
if($simpla->request->get('type') == 'sale' && $simpla->request->get('mode') == 'file')
{
$filename = $simpla->request->get('filename');
$f = fopen($dir.$filename, 'ab');
fwrite($f, file_get_contents('php://input'));
fclose($f);
$xml = simplexml_load_file($dir.$filename);
foreach($xml->Документ as $xml_order)
{
$order = null;
$order->id = $xml_order->Номер;
$existed_order = $simpla->orders->get_order(intval($order->id));
$order->date = $xml_order->Дата.' '.$xml_order->Время;
$order->name = $xml_order->Контрагенты->Контрагент->Наименование;
if(isset($xml_order->ЗначенияРеквизитов->ЗначениеРеквизита))
foreach($xml_order->ЗначенияРеквизитов->ЗначениеРеквизита as $r)
{
switch ($r->Наименование) {
case 'Проведен':
$proveden = ($r->Значение == 'true');
break;
case 'ПометкаУдаления':
$udalen = ($r->Значение == 'true');
break;
}
}
if($udalen)
$order->status = 3;
elseif($proveden)
$order->status = 1;
elseif(!$proveden)
$order->status = 0;
if($existed_order)
{
$simpla->orders->update_order($order->id, $order);
}
else
{
$order->id = $simpla->orders->add_order($order);
}
$purchases_ids = array();
// Товары
foreach($xml_order->Товары->Товар as $xml_product)
{
$purchase = null;
// Id товара и варианта (если есть) по 1С
$product_1c_id = $variant_1c_id = '';
@list($product_1c_id, $variant_1c_id) = explode('#', $xml_product->Ид);
if(empty($product_1c_id))
$product_1c_id = '';
if(empty($variant_1c_id))
$variant_1c_id = '';
// Ищем товар
$simpla->db->query('SELECT id FROM __products WHERE external_id=?', $product_1c_id);
$product_id = $simpla->db->result('id');
$simpla->db->query('SELECT id FROM __variants WHERE external_id=? AND product_id=?', $variant_1c_id, $product_id);
$variant_id = $simpla->db->result('id');
$purchase->order_id = $order->id;
$purchase->product_id = $product_id;
$purchase->variant_id = $variant_id;
$purchase->sku = $xml_product->Артикул;
$purchase->product_name = $xml_product->Наименование;
$purchase->amount = $xml_product->Количество;
$purchase->price = floatval($xml_product->ЦенаЗаЕдиницу);
if(isset($xml_product->Скидки->Скидка))
{
$discount = $xml_product->Скидки->Скидка->Процент;
$purchase->price = $purchase->price*(100-$discount)/100;
}
$simpla->db->query('SELECT id FROM __purchases WHERE order_id=? AND product_id=? AND variant_id=?', $order->id, $product_id, $variant_id);
$purchase_id = $simpla->db->result('id');
if(!empty($purchase_id))
$purchase_id = $simpla->orders->update_purchase($purchase_id, $purchase);
else
$purchase_id = $simpla->orders->add_purchase($purchase);
$purchases_ids[] = $purchase_id;
}
// Удалим покупки, которых нет в файле
foreach($simpla->orders->get_purchases(array('order_id'=>intval($order->id))) as $purchase)
{
if(!in_array($purchase->id, $purchases_ids))
$simpla->orders->delete_purchase($purchase->id);
}
$simpla->db->query('UPDATE __orders SET discount=0, total_price=? WHERE id=? LIMIT 1', $xml_order->Сумма, $order->id);
}
print "success";
$simpla->settings->last_1c_orders_export_date = date("Y-m-d H:i:s");
}
if($simpla->request->get('type') == 'sale' && $simpla->request->get('mode') == 'query')
{
$no_spaces = '<?xml version="1.0" encoding="utf-8"?>
<КоммерческаяИнформация ВерсияСхемы="2.04" ДатаФормирования="' . date ( 'Y-m-d' ) . '"></КоммерческаяИнформация>';
$xml = new SimpleXMLElement ( $no_spaces );
$orders = $simpla->orders->get_orders(array('modified_from'=>$simpla->settings->last_1c_orders_export_date));
foreach($orders as $order)
{
$date = new DateTime($order->date);
$doc = $xml->addChild ("Документ");
$doc->addChild ( "Ид", $order->id);
$doc->addChild ( "Номер", $order->id);
$doc->addChild ( "Дата", $date->format('Y-m-d'));
$doc->addChild ( "ХозОперация", "Заказ товара" );
$doc->addChild ( "Роль", "Продавец" );
$doc->addChild ( "Курс", "1" );
$doc->addChild ( "Сумма", $order->total_price);
$doc->addChild ( "Время", $date->format('H:i:s'));
$doc->addChild ( "Комментарий", $order->comment);
// Контрагенты
$k1 = $doc->addChild ( 'Контрагенты' );
$k1_1 = $k1->addChild ( 'Контрагент' );
$k1_2 = $k1_1->addChild ( "Ид", $order->name);
$k1_2 = $k1_1->addChild ( "Наименование", $order->name);
$k1_2 = $k1_1->addChild ( "Роль", "Покупатель" );
$k1_2 = $k1_1->addChild ( "ПолноеНаименование", $order->name );
// Доп параметры
$addr = $k1_1->addChild ('АдресРегистрации');
$addr->addChild ( 'Представление', $order->address );
$addrField = $addr->addChild ( 'АдресноеПоле' );
$addrField->addChild ( 'Тип', 'Страна' );
$addrField->addChild ( 'Значение', 'RU' );
$addrField = $addr->addChild ( 'АдресноеПоле' );
$addrField->addChild ( 'Тип', 'Регион' );
$addrField->addChild ( 'Значение', $order->address );
$contacts = $k1_1->addChild ( 'Контакты' );
$cont = $contacts->addChild ( 'Контакт' );
$cont->addChild ( 'Тип', 'Телефон' );
$cont->addChild ( 'Значение', $order->phone );
$cont = $contacts->addChild ( 'Контакт' );
$cont->addChild ( 'Тип', 'Почта' );
$cont->addChild ( 'Значение', $order->email );
$purchases = $simpla->orders->get_purchases(array('order_id'=>intval($order->id)));
$t1 = $doc->addChild ( 'Товары' );
foreach($purchases as $purchase)
{
if(!empty($purchase->product_id) && !empty($purchase->variant_id))
{
$simpla->db->query('SELECT external_id FROM __products WHERE id=?', $purchase->product_id);
$id_p = $simpla->db->result('external_id');
$simpla->db->query('SELECT external_id FROM __variants WHERE id=?', $purchase->variant_id);
$id_v = $simpla->db->result('external_id');
// Если нет внешнего ключа товара - указываем наш id
if(!empty($id_p))
{
$id = $id_p;
}
else
{
$simpla->db->query('UPDATE __products SET external_id=id WHERE id=?', $purchase->product_id);
$id = $purchase->product_id;
}
// Если нет внешнего ключа варианта - указываем наш id
if(!empty($id_v))
{
$id = $id.'#'.$id_v;
}
else
{
$simpla->db->query('UPDATE __variants SET external_id=id WHERE id=?', $purchase->variant_id);
$id = $id.'#'.$purchase->variant_id;
}
$t1_1 = $t1->addChild ( 'Товар' );
if($id)
$t1_2 = $t1_1->addChild ( "Ид", $id);
$t1_2 = $t1_1->addChild ( "Артикул", $purchase->sku);
$name = $purchase->product_name;
if($purchase->variant_name)
$name .= " $purchase->variant_name $id";
$t1_2 = $t1_1->addChild ( "Наименование", $name);
$t1_2 = $t1_1->addChild ( "ЦенаЗаЕдиницу", $purchase->price*(100-$order->discount)/100);
$t1_2 = $t1_1->addChild ( "Количество", $purchase->amount );
$t1_2 = $t1_1->addChild ( "Сумма", $purchase->amount*$purchase->price*(100-$order->discount)/100);
/*
$t1_2 = $t1_1->addChild ( "Скидки" );
$t1_3 = $t1_2->addChild ( "Скидка" );
$t1_4 = $t1_3->addChild ( "Сумма", $purchase->amount*$purchase->price*(100-$order->discount)/100);
$t1_4 = $t1_3->addChild ( "УчтеноВСумме", "true" );
*/
$t1_2 = $t1_1->addChild ( "ЗначенияРеквизитов" );
$t1_3 = $t1_2->addChild ( "ЗначениеРеквизита" );
$t1_4 = $t1_3->addChild ( "Наименование", "ВидНоменклатуры" );
$t1_4 = $t1_3->addChild ( "Значение", "Товар" );
$t1_2 = $t1_1->addChild ( "ЗначенияРеквизитов" );
$t1_3 = $t1_2->addChild ( "ЗначениеРеквизита" );
$t1_4 = $t1_3->addChild ( "Наименование", "ТипНоменклатуры" );
$t1_4 = $t1_3->addChild ( "Значение", "Товар" );
}
}
// Доставка
if($order->delivery_price>0 && !$order->separate_delivery)
{
$t1 = $t1->addChild ( 'Товар' );
$t1->addChild ( "Ид", 'ORDER_DELIVERY');
$t1->addChild ( "Наименование", 'Доставка');
$t1->addChild ( "ЦенаЗаЕдиницу", $order->delivery_price);
$t1->addChild ( "Количество", 1 );
$t1->addChild ( "Сумма", $order->delivery_price);
$t1_2 = $t1->addChild ( "ЗначенияРеквизитов" );
$t1_3 = $t1_2->addChild ( "ЗначениеРеквизита" );
$t1_4 = $t1_3->addChild ( "Наименование", "ВидНоменклатуры" );
$t1_4 = $t1_3->addChild ( "Значение", "Услуга" );
$t1_2 = $t1->addChild ( "ЗначенияРеквизитов" );
$t1_3 = $t1_2->addChild ( "ЗначениеРеквизита" );
$t1_4 = $t1_3->addChild ( "Наименование", "ТипНоменклатуры" );
$t1_4 = $t1_3->addChild ( "Значение", "Услуга" );
}
// Статус
if($order->status == 1)
{
$s1_2 = $doc->addChild ( "ЗначенияРеквизитов" );
$s1_3 = $s1_2->addChild ( "ЗначениеРеквизита" );
$s1_3->addChild ( "Наименование", "Статус заказа" );
$s1_3->addChild ( "Значение", "[N] Принят" );
}
if($order->status == 2)
{
$s1_2 = $doc->addChild ( "ЗначенияРеквизитов" );
$s1_3 = $s1_2->addChild ( "ЗначениеРеквизита" );
$s1_3->addChild ( "Наименование", "Статус заказа" );
$s1_3->addChild ( "Значение", "[F] Доставлен" );
}
if($order->status == 3)
{
$s1_2 = $doc->addChild ( "ЗначенияРеквизитов" );
$s1_3 = $s1_2->addChild ( "ЗначениеРеквизита" );
$s1_3->addChild ( "Наименование", "Отменен" );
$s1_3->addChild ( "Значение", "true" );
}
}
header ( "Content-type: text/xml; charset=utf-8" );
print "\xEF\xBB\xBF";
print $xml->asXML ();
$simpla->settings->last_1c_orders_export_date = date("Y-m-d H:i:s");
}
if($simpla->request->get('type') == 'sale' && $simpla->request->get('mode') == 'success')
{
$simpla->settings->last_1c_orders_export_date = date("Y-m-d H:i:s");
}
if($simpla->request->get('type') == 'catalog' && $simpla->request->get('mode') == 'checkauth')
{
print "success\n";
print session_name()."\n";
print session_id();
}
if($simpla->request->get('type') == 'catalog' && $simpla->request->get('mode') == 'init')
{
$tmp_files = glob($dir.'*.*');
if(is_array($tmp_files))
foreach($tmp_files as $v)
{
unlink($v);
}
unset($_SESSION['last_1c_imported_variant_num']);
unset($_SESSION['last_1c_imported_product_num']);
unset($_SESSION['features_mapping']);
unset($_SESSION['categories_mapping']);
unset($_SESSION['brand_id_option']);
print "zip=no\n";
print "file_limit=1000000\n";
}
if($simpla->request->get('type') == 'catalog' && $simpla->request->get('mode') == 'file')
{
$filename = basename($simpla->request->get('filename'));
$f = fopen($dir.$filename, 'ab');
fwrite($f, file_get_contents('php://input'));
fclose($f);
print "success\n";
}
if($simpla->request->get('type') == 'catalog' && $simpla->request->get('mode') == 'import')
{
$filename = basename($simpla->request->get('filename'));
if($filename === 'import.xml')
{
// Категории и свойства (только в первом запросе пакетной передачи)
if(!isset($_SESSION['last_1c_imported_product_num']))
{
$z = new XMLReader;
$z->open($dir.$filename);
while ($z->read() && $z->name !== 'Классификатор');
$xml = new SimpleXMLElement($z->readOuterXML());
$z->close();
import_categories($xml);
import_features($xml);
}
// Товары
$z = new XMLReader;
$z->open($dir.$filename);
while ($z->read() && $z->name !== 'Товар');
// Последний товар, на котором остановились
$last_product_num = 0;
if(isset($_SESSION['last_1c_imported_product_num']))
$last_product_num = $_SESSION['last_1c_imported_product_num'];
// Номер текущего товара
$current_product_num = 0;
while($z->name === 'Товар')
{
if($current_product_num >= $last_product_num)
{
$xml = new SimpleXMLElement($z->readOuterXML());
// Товары
import_product($xml);
$exec_time = microtime(true) - $start_time;
if($exec_time+1>=$max_exec_time)
{
header ( "Content-type: text/xml; charset=utf-8" );
print "\xEF\xBB\xBF";
print "progress\r\n";
print "Выгружено товаров: $current_product_num\r\n";
$_SESSION['last_1c_imported_product_num'] = $current_product_num;
exit();
}
}
$z->next('Товар');
$current_product_num ++;
}
$z->close();
print "success";
//unlink($dir.$filename);
unset($_SESSION['last_1c_imported_product_num']);
}
elseif($filename === 'offers.xml')
{
// Варианты
$z = new XMLReader;
$z->open($dir.$filename);
while ($z->read() && $z->name !== 'Предложение');
// Последний вариант, на котором остановились
$last_variant_num = 0;
if(isset($_SESSION['last_1c_imported_variant_num']))
$last_variant_num = $_SESSION['last_1c_imported_variant_num'];
// Номер текущего товара
$current_variant_num = 0;
while($z->name === 'Предложение')
{
if($current_variant_num >= $last_variant_num)
{
$xml = new SimpleXMLElement($z->readOuterXML());
// Варианты
import_variant($xml);
$exec_time = microtime(true) - $start_time;
if($exec_time+1>=$max_exec_time)
{
header ( "Content-type: text/xml; charset=utf-8" );
print "\xEF\xBB\xBF";
print "progress\r\n";
print "Выгружено ценовых предложений: $current_variant_num\r\n";
$_SESSION['last_1c_imported_variant_num'] = $current_variant_num;
exit();
}
}
$z->next('Предложение');
$current_variant_num ++;
}
$z->close();
print "success";
//unlink($dir.$filename);
unset($_SESSION['last_1c_imported_variant_num']);
}
}
function import_categories($xml, $parent_id = 0)
{
global $simpla;
global $dir;
if(isset($xml->Группы->Группа))
foreach ($xml->Группы->Группа as $xml_group)
{
$simpla->db->query('SELECT id FROM __categories WHERE external_id=?', $xml_group->Ид);
$category_id = $simpla->db->result('id');
if(empty($category_id))
$category_id = $simpla->categories->add_category(array('parent_id'=>$parent_id, 'external_id'=>$xml_group->Ид, 'url'=>translit($xml_group->Наименование), 'name'=>$xml_group->Наименование, 'meta_title'=>$xml_group->Наименование, 'meta_keywords'=>$xml_group->Наименование, 'meta_description'=>$xml_group->Наименование ));
$_SESSION['categories_mapping'][strval($xml_group->Ид)] = $category_id;
import_categories($xml_group, $category_id);
}
}
function import_features($xml)
{
global $simpla;
global $dir;
global $brand_option_name;
$property = array();
if(isset($xml->Свойства->СвойствоНоменклатуры))
$property = $xml->Свойства->СвойствоНоменклатуры;
if(isset($xml->Свойства->Свойство))
$property = $xml->Свойства->Свойство;
foreach ($property as $xml_feature)
{
// Если свойство содержит производителя товаров
if($xml_feature->Наименование == $brand_option_name)
{
// Запомним в сессии Ид свойства с производителем
$_SESSION['brand_option_id'] = strval($xml_feature->Ид);
}
// Иначе обрабатываем как обычной свойство товара
else
{
$simpla->db->query('SELECT id FROM __features WHERE name=?', strval($xml_feature->Наименование));
$feature_id = $simpla->db->result('id');
if(empty($feature_id))
$feature_id = $simpla->features->add_feature(array('name'=>strval($xml_feature->Наименование)));
$_SESSION['features_mapping'][strval($xml_feature->Ид)] = $feature_id;
}
}
}
function import_product($xml_product)
{
global $simpla;
global $dir;
global $brand_option_name;
global $full_update;
// Товары
// Id товара и варианта (если есть) по 1С
@list($product_1c_id, $variant_1c_id) = explode('#', $xml_product->Ид);
if(empty($variant_1c_id))
$variant_1c_id = '';
// Ид категории
if(isset($xml_product->Группы->Ид))
$category_id = $_SESSION['categories_mapping'][strval($xml_product->Группы->Ид)];
// Подгатавливаем вариант
$variant_id = null;
$variant = null;
$values = array();
if(isset($xml_product->ХарактеристикиТовара->ХарактеристикаТовара))
foreach($xml_product->ХарактеристикиТовара->ХарактеристикаТовара as $xml_property)
$values[] = $xml_property->Значение;
if(!empty($values))
$variant->name = implode(', ', $values);
$variant->sku = (string)$xml_product->Артикул;
$variant->external_id = $variant_1c_id;
// Ищем товар
$simpla->db->query('SELECT id FROM __products WHERE external_id=?', $product_1c_id);
$product_id = $simpla->db->result('id');
if(empty($product_id) && !empty($variant->sku))
{
$simpla->db->query('SELECT product_id, id FROM __variants WHERE sku=?', $variant->sku);
$res = $simpla->db->result();
$product_id = $res->product_id;
$variant_id = $res->id;
}
// Если такого товара не нашлось
if(empty($product_id))
{
// Добавляем товар
$description = '';
if(!empty($xml_product->Описание))
$description = $xml_product->Описание;
$product_id = $simpla->products->add_product(array('external_id'=>$product_1c_id, 'url'=>translit($xml_product->Наименование), 'name'=>$xml_product->Наименование, 'meta_title'=>$xml_product->Наименование, 'meta_keywords'=>$xml_product->Наименование, 'meta_description'=>$xml_product->$description, 'annotation'=>$description, 'body'=>$description));
// Добавляем товар в категории
if(isset($category_id))
$simpla->categories->add_product_category($product_id, $category_id);
// Добавляем изображение товара
if(isset($xml_product->Картинка))
{
foreach($xml_product->Картинка as $img)
{
$image = basename($xml_product->Картинка);
if(!empty($image) && is_file($dir.$image) && is_writable($simpla->config->original_images_dir))
{
rename($dir.$image, $simpla->config->original_images_dir.$image);
$simpla->products->add_image($product_id, $image);
}
}
}
}
//Если нашелся товар
else
{
if(empty($variant_id) && !empty($variant_1c_id))
{
$simpla->db->query('SELECT id FROM __variants WHERE external_id=? AND product_id=?', $variant_1c_id, $product_id);
$variant_id = $simpla->db->result('id');
}
elseif(empty($variant_id) && empty($variant_1c_id))
{
$simpla->db->query('SELECT id FROM __variants WHERE product_id=?', $product_id);
$variant_id = $simpla->db->result('id');
}
// Обновляем товар
if($full_update)
{
$description = '';
if(!empty($xml_product->Описание))
$description = $xml_product->Описание;
$product_id = $simpla->products->update_product($product_id, array('external_id'=>$product_1c_id, 'url'=>translit($xml_product->Наименование), 'name'=>$xml_product->Наименование, 'meta_title'=>$xml_product->Наименование, 'meta_keywords'=>$xml_product->Наименование, 'meta_description'=>$xml_product->$description, 'annotation'=>$description, 'body'=>$description));
// Обновляем категорию товара
if(isset($category_id) && !empty($product_id))
{
$query = $simpla->db->placehold('DELETE FROM __products_categories WHERE product_id=?', $product_id);
$simpla->db->query($query);
$simpla->categories->add_product_category($product_id, $category_id);
}
}
// Обновляем изображение товара
if(isset($xml_product->Картинка))
{
foreach($xml_product->Картинка as $img)
{
$image = basename($img);
if(!empty($image) && is_file($dir.$image) && is_writable($simpla->config->original_images_dir))
{
$simpla->db->query('SELECT id FROM __images WHERE product_id=? ORDER BY position LIMIT 1', $product_id);
$img_id = $simpla->db->result('id');
if(!empty($img_id))
$simpla->products->delete_image($img_id);
rename($dir.$image, $simpla->config->original_images_dir.$image);
$simpla->products->add_image($product_id, $image);
}
}
}
}
// Если не найден вариант, добавляем вариант один к товару
if(empty($variant_id))
{
$variant->product_id = $product_id;
$variant->stock = 0;
$variant_id = $simpla->variants->add_variant($variant);
}
else
{
$simpla->variants->update_variant($variant_id, $variant);
}
// Свойства товара
if(isset($xml_product->ЗначенияСвойств->ЗначенияСвойства))
{
foreach ($xml_product->ЗначенияСвойств->ЗначенияСвойства as $xml_option)
{
if(isset($_SESSION['features_mapping'][strval($xml_option->Ид)]))
{
$feature_id = $_SESSION['features_mapping'][strval($xml_option->Ид)];
if(isset($category_id) && !empty($feature_id))
{
$simpla->features->add_feature_category($feature_id, $category_id);
$values = array();
foreach($xml_option->Значение as $xml_value)
$values[] = strval($xml_value);
$simpla->features->update_option($product_id, $feature_id, implode(' ,', $values));
}
}
// Если свойство оказалось названием бренда
elseif(isset($_SESSION['brand_option_id']) && !empty($xml_option->Значение))
{
$brand_name = strval($xml_option->Значение);
// Добавим бренд
// Найдем его по имени
$simpla->db->query('SELECT id FROM __brands WHERE name=?', $brand_name);
if(!$brand_id = $simpla->db->result('id'))
// Создадим, если не найден
$brand_id = $simpla->brands->add_brand(array('name'=>$brand_name, 'meta_title'=>$brand_name, 'meta_keywords'=>$brand_name, 'meta_description'=>$brand_name, 'url'=>translit($brand_name)));
if(!empty($brand_id))
$simpla->products->update_product($product_id, array('brand_id'=>$brand_id));
}
}
}
// Если нужно - удаляем вариант или весь товар
if($xml_product->Статус == 'Удален')
{
$simpla->variants->delete_variant($variant_id);
$simpla->db->query('SELECT count(id) as variants_num FROM __variants WHERE product_id=?', $product_id);
if($simpla->db->result('variants_num') == 0)
$simpla->products->delete_product($product_id);
}
}
function import_variant($xml_variant)
{
global $simpla;
global $dir;
$variant = null;
// Id товара и варианта (если есть) по 1С
@list($product_1c_id, $variant_1c_id) = explode('#', $xml_variant->Ид);
if(empty($variant_1c_id))
$variant_1c_id = '';
$simpla->db->query('SELECT v.id FROM __variants v WHERE v.external_id=? AND product_id=(SELECT p.id FROM __products p WHERE p.external_id=? LIMIT 1)', $variant_1c_id, $product_1c_id);
$variant_id = $simpla->db->result('id');
$variant->price = $xml_variant->Цены->Цена->ЦенаЗаЕдиницу;
// Конвертируем цену из валюты 1С в базовую валюту магазина
if(!empty($xml_variant->Цены->Цена->Валюта))
{
// Ищем валюту по коду
$simpla->db->query("SELECT id, rate_from, rate_to FROM __currencies WHERE code like ?", $xml_variant->Цены->Цена->Валюта);
$variant_currency = $simpla->db->result();
// Если не нашли - ищем по обозначению
if(empty($variant_currency))
{
$simpla->db->query("SELECT id, rate_from, rate_to FROM __currencies WHERE sign like ?", $xml_variant->Цены->Цена->Валюта);
$variant_currency = $simpla->db->result();
}
// Если нашли валюту - конвертируем из нее в базовую
if($variant_currency && $variant_currency->rate_from>0 && $variant_currency->rate_to>0)
{
$variant->price = floatval($variant->price)*$variant_currency->rate_to/$variant_currency->rate_from;
}
}
$variant->stock = $xml_variant->Количество;
$simpla->variants->update_variant($variant_id, $variant);
}
function translit($text)
{
$ru = explode('-', "А-а-Б-б-В-в-Ґ-ґ-Г-г-Д-д-Е-е-Ё-ё-Є-є-Ж-ж-З-з-И-и-І-і-Ї-ї-Й-й-К-к-Л-л-М-м-Н-н-О-о-П-п-Р-р-С-с-Т-т-У-у-Ф-ф-Х-х-Ц-ц-Ч-ч-Ш-ш-Щ-щ-Ъ-ъ-Ы-ы-Ь-ь-Э-э-Ю-ю-Я-я");
$en = explode('-', "A-a-B-b-V-v-G-g-G-g-D-d-E-e-E-e-E-e-ZH-zh-Z-z-I-i-I-i-I-i-J-j-K-k-L-l-M-m-N-n-O-o-P-p-R-r-S-s-T-t-U-u-F-f-H-h-TS-ts-CH-ch-SH-sh-SCH-sch---Y-y---E-e-YU-yu-YA-ya");
$res = str_replace($ru, $en, $text);
$res = preg_replace("/[\s]+/ui", '-', $res);
$res = strtolower(preg_replace("/[^0-9a-zа\-]+/ui", '', $res));
return $res;
}

59
simpla/index.php Normal file
View File

@@ -0,0 +1,59 @@
<?php
chdir('..');
// Засекаем время
$time_start = microtime(true);
session_start();
$_SESSION['id'] = session_id();
@ini_set('session.gc_maxlifetime', 86400); // 86400 = 24 часа
@ini_set('session.cookie_lifetime', 0); // 0 - пока браузер не закрыт
require_once('simpla/IndexAdmin.php');
// Кеширование в админке нам не нужно
Header("Cache-Control: no-cache, must-revalidate");
header("Expires: -1");
Header("Pragma: no-cache");
// Установим переменную сессии, чтоб фронтенд нас узнал как админа
$_SESSION['admin'] = 'admin';
$backend = new IndexAdmin();
// Проверка сессии для защиты от xss
if(!$backend->request->check_session())
{
unset($_POST);
trigger_error('Session expired', E_USER_WARNING);
}
print $backend->fetch();
// Отладочная информация
if($backend->config->debug)
{
print "<!--\r\n";
$i = 0;
$sql_time = 0;
foreach($page->db->queries as $q)
{
$i++;
print "$i.\t$q->exec_time sec\r\n$q->sql\r\n\r\n";
$sql_time += $q->exec_time;
}
$time_end = microtime(true);
$exec_time = $time_end-$time_start;
if(function_exists('memory_get_peak_usage'))
print "memory peak usage: ".memory_get_peak_usage()." bytes\r\n";
print "page generation time: ".$exec_time." seconds\r\n";
print "sql queries time: ".$sql_time." seconds\r\n";
print "php run time: ".($exec_time-$sql_time)." seconds\r\n";
print "-->";
}

504
simpla/pclzip/gnu-lgpl.txt Normal file
View File

@@ -0,0 +1,504 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

5694
simpla/pclzip/pclzip.lib.php Normal file

File diff suppressed because it is too large Load Diff

421
simpla/pclzip/readme.txt Normal file
View File

@@ -0,0 +1,421 @@
// --------------------------------------------------------------------------------
// PclZip 2.8.2 - readme.txt
// --------------------------------------------------------------------------------
// License GNU/LGPL - August 2009
// Vincent Blavet - vincent@phpconcept.net
// http://www.phpconcept.net
// --------------------------------------------------------------------------------
// $Id: readme.txt,v 1.60 2009/09/30 20:35:21 vblavet Exp $
// --------------------------------------------------------------------------------
0 - Sommaire
============
1 - Introduction
2 - What's new
3 - Corrected bugs
4 - Known bugs or limitations
5 - License
6 - Warning
7 - Documentation
8 - Author
9 - Contribute
1 - Introduction
================
PclZip is a library that allow you to manage a Zip archive.
Full documentation about PclZip can be found here : http://www.phpconcept.net/pclzip
2 - What's new
==============
Version 2.8.2 :
- PCLZIP_CB_PRE_EXTRACT and PCLZIP_CB_POST_EXTRACT are now supported with
extraction as a string (PCLZIP_OPT_EXTRACT_AS_STRING). The string
can also be modified in the post-extract call back.
**Bugs correction :
- PCLZIP_OPT_REMOVE_ALL_PATH was not working correctly
- Remove use of eval() and do direct call to callback functions
- Correct support of 64bits systems (Thanks to WordPress team)
Version 2.8.1 :
- Move option PCLZIP_OPT_BY_EREG to PCLZIP_OPT_BY_PREG because ereg() is
deprecated in PHP 5.3. When using option PCLZIP_OPT_BY_EREG, PclZip will
automatically replace it by PCLZIP_OPT_BY_PREG.
Version 2.8 :
- Improve extraction of zip archive for large files by using temporary files
This feature is working like the one defined in r2.7.
Options are renamed : PCLZIP_OPT_TEMP_FILE_ON, PCLZIP_OPT_TEMP_FILE_OFF,
PCLZIP_OPT_TEMP_FILE_THRESHOLD
- Add a ratio constant PCLZIP_TEMPORARY_FILE_RATIO to configure the auto
sense of temporary file use.
- Bug correction : Reduce filepath in returned file list to remove ennoying
'.//' preambule in file path.
Version 2.7 :
- Improve creation of zip archive for large files :
PclZip will now autosense the configured memory and use temporary files
when large file is suspected.
This feature can also ne triggered by manual options in create() and add()
methods. 'PCLZIP_OPT_ADD_TEMP_FILE_ON' force the use of temporary files,
'PCLZIP_OPT_ADD_TEMP_FILE_OFF' disable the autosense technic,
'PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD' allow for configuration of a size
threshold to use temporary files.
Using "temporary files" rather than "memory" might take more time, but
might give the ability to zip very large files :
Tested on my win laptop with a 88Mo file :
Zip "in-memory" : 18sec (max_execution_time=30, memory_limit=180Mo)
Zip "tmporary-files" : 23sec (max_execution_time=30, memory_limit=30Mo)
- Replace use of mktime() by time() to limit the E_STRICT error messages.
- Bug correction : When adding files with full windows path (drive letter)
PclZip is now working. Before, if the drive letter is not the default
path, PclZip was not able to add the file.
Version 2.6 :
- Code optimisation
- New attributes PCLZIP_ATT_FILE_COMMENT gives the ability to
add a comment for a specific file. (Don't really know if this is usefull)
- New attribute PCLZIP_ATT_FILE_CONTENT gives the ability to add a string
as a file.
- New attribute PCLZIP_ATT_FILE_MTIME modify the timestamp associated with
a file.
- Correct a bug. Files archived with a timestamp with 0h0m0s were extracted
with current time
- Add CRC value in the informations returned back for each file after an
action.
- Add missing closedir() statement.
- When adding a folder, and removing the path of this folder, files were
incorrectly added with a '/' at the beginning. Which means files are
related to root in unix systems. Corrected.
- Add conditional if before constant definition. This will allow users
to redefine constants without changing the file, and then improve
upgrade of pclzip code for new versions.
Version 2.5 :
- Introduce the ability to add file/folder with individual properties (file descriptor).
This gives for example the ability to change the filename of a zipped file.
. Able to add files individually
. Able to change full name
. Able to change short name
. Compatible with global options
- New attributes : PCLZIP_ATT_FILE_NAME, PCLZIP_ATT_FILE_NEW_SHORT_NAME, PCLZIP_ATT_FILE_NEW_FULL_NAME
- New error code : PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE
- Add a security control feature. PclZip can extract any file in any folder
of a system. People may use this to upload a zip file and try to override
a system file. The PCLZIP_OPT_EXTRACT_DIR_RESTRICTION will give the
ability to forgive any directory transversal behavior.
- New PCLZIP_OPT_EXTRACT_DIR_RESTRICTION : check extraction path
- New error code : PCLZIP_ERR_DIRECTORY_RESTRICTION
- Modification in PclZipUtilPathInclusion() : dir and path beginning with ./ will be prepend
by current path (getcwd())
Version 2.4 :
- Code improvment : try to speed up the code by removing unusefull call to pack()
- Correct bug in delete() : delete() should be called with no argument. This was not
the case in 2.3. This is corrected in 2.4.
- Correct a bug in path_inclusion function. When the path has several '../../', the
result was bad.
- Add a check for magic_quotes_runtime configuration. If enabled, PclZip will
disable it while working and det it back to its original value.
This resolve a lots of bad formated archive errors.
- Bug correction : PclZip now correctly unzip file in some specific situation,
when compressed content has same size as uncompressed content.
- Bug correction : When selecting option 'PCLZIP_OPT_REMOVE_ALL_PATH',
directories are not any more created.
- Code improvment : correct unclosed opendir(), better handling of . and .. in
loops.
Version 2.3 :
- Correct a bug with PHP5 : affecting the value 0xFE49FFE0 to a variable does not
give the same result in PHP4 and PHP5 ....
Version 2.2 :
- Try development of PCLZIP_OPT_CRYPT .....
However this becomes to a stop. To crypt/decrypt I need to multiply 2 long integers,
the result (greater than a long) is not supported by PHP. Even the use of bcmath
functions does not help. I did not find yet a solution ...;
- Add missing '/' at end of directory entries
- Check is a file is encrypted or not. Returns status 'unsupported_encryption' and/or
error code PCLZIP_ERR_UNSUPPORTED_ENCRYPTION.
- Corrected : Bad "version need to extract" field in local file header
- Add private method privCheckFileHeaders() in order to check local and central
file headers. PclZip is now supporting purpose bit flag bit 3. Purpose bit flag bit 3 gives
the ability to have a local file header without size, compressed size and crc filled.
- Add a generic status 'error' for file status
- Add control of compression type. PclZip only support deflate compression method.
Before v2.2, PclZip does not check the compression method used in an archive while
extracting. With v2.2 PclZip returns a new error status for a file using an unsupported
compression method. New status is "unsupported_compression". New error code is
PCLZIP_ERR_UNSUPPORTED_COMPRESSION.
- Add optional attribute PCLZIP_OPT_STOP_ON_ERROR. This will stop the extract of files
when errors like 'a folder with same name exists' or 'a newer file exists' or
'a write protected file' exists, rather than set a status for the concerning file
and resume the extract of the zip.
- Add optional attribute PCLZIP_OPT_REPLACE_NEWER. This will force, during an extract' the
replacement of the file, even if a newer version of the file exists.
Note that today if a file with the same name already exists but is older it will be
replaced by the extracted one.
- Improve PclZipUtilOption()
- Support of zip archive with trailing bytes. Before 2.2, PclZip checks that the central
directory structure is the last data in the archive. Crypt encryption/decryption of
zip archive put trailing 0 bytes after decryption. PclZip is now supporting this.
Version 2.1 :
- Add the ability to abort the extraction by using a user callback function.
The user can now return the value '2' in its callback which indicates to stop the
extraction. For a pre call-back extract is stopped before the extration of the current
file. For a post call back, the extraction is stopped after.
- Add the ability to extract a file (or several files) directly in the standard output.
This is done by the new parameter PCLZIP_OPT_EXTRACT_IN_OUTPUT with method extract().
- Add support for parameters PCLZIP_OPT_COMMENT, PCLZIP_OPT_ADD_COMMENT,
PCLZIP_OPT_PREPEND_COMMENT. This will create, replace, add, or prepend comments
in the zip archive.
- When merging two archives, the comments are not any more lost, but merged, with a
blank space separator.
- Corrected bug : Files are not deleted when all files are asked to be deleted.
- Corrected bug : Folders with name '0' made PclZip to abort the create or add feature.
Version 2.0 :
***** Warning : Some new features may break the backward compatibility for your scripts.
Please carefully read the readme file.
- Add the ability to delete by Index, name and regular expression. This feature is
performed by the method delete(), which uses the optional parameters
PCLZIP_OPT_BY_INDEX, PCLZIP_OPT_BY_NAME, PCLZIP_OPT_BY_EREG or PCLZIP_OPT_BY_PREG.
- Add the ability to extract by regular expression. To extract by regexp you must use the method
extract(), with the option PCLZIP_OPT_BY_EREG or PCLZIP_OPT_BY_PREG
(depending if you want to use ereg() or preg_match() syntax) followed by the
regular expression pattern.
- Add the ability to extract by index, directly with the extract() method. This is a
code improvment of the extractByIndex() method.
- Add the ability to extract by name. To extract by name you must use the method
extract(), with the option PCLZIP_OPT_BY_NAME followed by the filename to
extract or an array of filenames to extract. To extract all a folder, use the folder
name rather than the filename with a '/' at the end.
- Add the ability to add files without compression. This is done with a new attribute
which is PCLZIP_OPT_NO_COMPRESSION.
- Add the attribute PCLZIP_OPT_EXTRACT_AS_STRING, which allow to extract a file directly
in a string without using any file (or temporary file).
- Add constant PCLZIP_SEPARATOR for static configuration of filename separators in a single string.
The default separator is now a comma (,) and not any more a blank space.
THIS BREAK THE BACKWARD COMPATIBILITY : Please check if this may have an impact with
your script.
- Improve algorythm performance by removing the use of temporary files when adding or
extracting files in an archive.
- Add (correct) detection of empty filename zipping. This can occurs when the removed
path is the same
as a zipped dir. The dir is not zipped (['status'] = filtered), only its content.
- Add better support for windows paths (thanks for help from manus@manusfreedom.com).
- Corrected bug : When the archive file already exists with size=0, the add() method
fails. Corrected in 2.0.
- Remove the use of OS_WINDOWS constant. Use php_uname() function rather.
- Control the order of index ranges in extract by index feature.
- Change the internal management of folders (better handling of internal flag).
Version 1.3 :
- Removing the double include check. This is now done by include_once() and require_once()
PHP directives.
- Changing the error handling mecanism : Remove the use of an external error library.
The former PclError...() functions are replaced by internal equivalent methods.
By changing the environment variable PCLZIP_ERROR_EXTERNAL you can still use the former library.
Introducing the use of constants for error codes rather than integer values. This will help
in futur improvment.
Introduction of error handling functions like errorCode(), errorName() and errorInfo().
- Remove the deprecated use of calling function with arguments passed by reference.
- Add the calling of extract(), extractByIndex(), create() and add() functions
with variable options rather than fixed arguments.
- Add the ability to remove all the file path while extracting or adding,
without any need to specify the path to remove.
This is available for extract(), extractByIndex(), create() and add() functionS by using
the new variable options parameters :
- PCLZIP_OPT_REMOVE_ALL_PATH : by indicating this option while calling the fct.
- Ability to change the mode of a file after the extraction (chmod()).
This is available for extract() and extractByIndex() functionS by using
the new variable options parameters.
- PCLZIP_OPT_SET_CHMOD : by setting the value of this option.
- Ability to definition call-back options. These call-back will be called during the adding,
or the extracting of file (extract(), extractByIndex(), create() and add() functions) :
- PCLZIP_CB_PRE_EXTRACT : will be called before each extraction of a file. The user
can trigerred the change the filename of the extracted file. The user can triggered the
skip of the extraction. This is adding a 'skipped' status in the file list result value.
- PCLZIP_CB_POST_EXTRACT : will be called after each extraction of a file.
Nothing can be triggered from that point.
- PCLZIP_CB_PRE_ADD : will be called before each add of a file. The user
can trigerred the change the stored filename of the added file. The user can triggered the
skip of the add. This is adding a 'skipped' status in the file list result value.
- PCLZIP_CB_POST_ADD : will be called after each add of a file.
Nothing can be triggered from that point.
- Two status are added in the file list returned as function result : skipped & filename_too_long
'skipped' is used when a call-back function ask for skipping the file.
'filename_too_long' is used while adding a file with a too long filename to archive (the file is
not added)
- Adding the function PclZipUtilPathInclusion(), that check the inclusion of a path into
a directory.
- Add a check of the presence of the archive file before some actions (like list, ...)
- Add the initialisation of field "index" in header array. This means that by
default index will be -1 when not explicitly set by the methods.
Version 1.2 :
- Adding a duplicate function.
- Adding a merge function. The merge function is a "quick merge" function,
it just append the content of an archive at the end of the first one. There
is no check for duplicate files or more recent files.
- Improve the search of the central directory end.
Version 1.1.2 :
- Changing the license of PclZip. PclZip is now released under the GNU / LGPL license
(see License section).
- Adding the optional support of a static temporary directory. You will need to configure
the constant PCLZIP_TEMPORARY_DIR if you want to use this feature.
- Improving the rename() function. In some cases rename() does not work (different
Filesystems), so it will be replaced by a copy() + unlink() functions.
Version 1.1.1 :
- Maintenance release, no new feature.
Version 1.1 :
- New method Add() : adding files in the archive
- New method ExtractByIndex() : partial extract of the archive, files are identified by
their index in the archive
- New method DeleteByIndex() : delete some files/folder entries from the archive,
files are identified by their index in the archive.
- Adding a test of the zlib extension presence. If not present abort the script.
Version 1.0.1 :
- No new feature
3 - Corrected bugs
==================
Corrected in Version 2.0 :
- Corrected : During an extraction, if a call-back fucntion is used and try to skip
a file, all the extraction process is stopped.
Corrected in Version 1.3 :
- Corrected : Support of static synopsis for method extract() is broken.
- Corrected : invalid size of archive content field (0xFF) should be (0xFFFF).
- Corrected : When an extract is done with a remove_path parameter, the entry for
the directory with exactly the same path is not skipped/filtered.
- Corrected : extractByIndex() and deleteByIndex() were not managing index in the
right way. For example indexes '1,3-5,11' will only extract files 1 and 11. This
is due to a sort of the index resulting table that puts 11 before 3-5 (sort on
string and not interger). The sort is temporarilly removed, this means that
you must provide a sorted list of index ranges.
Corrected in Version 1.2 :
- Nothing.
Corrected in Version 1.1.2 :
- Corrected : Winzip is unable to delete or add new files in a PclZip created archives.
Corrected in Version 1.1.1 :
- Corrected : When archived file is not compressed (0% compression), the
extract method fails.
Corrected in Version 1.1 :
- Corrected : Adding a complete tree of folder may result in a bad archive
creation.
Corrected in Version 1.0.1 :
- Corrected : Error while compressing files greater than PCLZIP_READ_BLOCK_SIZE (default=1024).
4 - Known bugs or limitations
=============================
Please publish bugs reports in SourceForge :
http://sourceforge.net/tracker/?group_id=40254&atid=427564
In Version 2.x :
- PclZip does only support file uncompressed or compressed with deflate (compression method 8)
- PclZip does not support password protected zip archive
- Some concern were seen when changing mtime of a file while archiving.
Seems to be linked to Daylight Saving Time (PclTest_changing_mtime).
In Version 1.2 :
- merge() methods does not check for duplicate files or last date of modifications.
In Version 1.1 :
- Limitation : Using 'extract' fields in the file header in the zip archive is not supported.
- WinZip is unable to delete a single file in a PclZip created archive. It is also unable to
add a file in a PclZip created archive. (Corrected in v.1.2)
In Version 1.0.1 :
- Adding a complete tree of folder may result in a bad archive
creation. (Corrected in V.1.1).
- Path given to methods must be in the unix format (/) and not the Windows format (\).
Workaround : Use only / directory separators.
- PclZip is using temporary files that are sometime the name of the file with a .tmp or .gz
added suffix. Files with these names may already exist and may be overwritten.
Workaround : none.
- PclZip does not check if the zlib extension is present. If it is absent, the zip
file is not created and the lib abort without warning.
Workaround : enable the zlib extension on the php install
In Version 1.0 :
- Error while compressing files greater than PCLZIP_READ_BLOCK_SIZE (default=1024).
(Corrected in v.1.0.1)
- Limitation : Multi-disk zip archive are not supported.
5 - License
===========
Since version 1.1.2, PclZip Library is released under GNU/LGPL license.
This library is free, so you can use it at no cost.
HOWEVER, if you release a script, an application, a library or any kind of
code using PclZip library (or a part of it), YOU MUST :
- Indicate in the documentation (or a readme file), that your work
uses PclZip Library, and make a reference to the author and the web site
http://www.phpconcept.net
- Gives the ability to the final user to update the PclZip libary.
I will also appreciate that you send me a mail (vincent@phpconcept.net), just to
be aware that someone is using PclZip.
For more information about GNU/LGPL license : http://www.gnu.org
6 - Warning
=================
This library and the associated files are non commercial, non professional work.
It should not have unexpected results. However if any damage is caused by this software
the author can not be responsible.
The use of this software is at the risk of the user.
7 - Documentation
=================
PclZip User Manuel is available in English on PhpConcept : http://www.phpconcept.net/pclzip/man/en/index.php
A Russian translation was done by Feskov Kuzma : http://php.russofile.ru/ru/authors/unsort/zip/
8 - Author
==========
This software was written by Vincent Blavet (vincent@phpconcept.net) on its leasure time.
9 - Contribute
==============
If you want to contribute to the development of PclZip, please contact vincent@phpconcept.net.
If you can help in financing PhpConcept hosting service, please go to
http://www.phpconcept.net/soutien.php

3
simpla/phpinfo.php Normal file
View File

@@ -0,0 +1,3 @@
<?php
phpinfo();
?>

28
simpla/rest/.htaccess Normal file
View File

@@ -0,0 +1,28 @@
<Limit GET POST PUT DELETE>
Allow from all
</Limit>
AddDefaultCharset UTF-8
RewriteEngine on
# Товары
RewriteRule ^products/?$ index.php?resource=products [L,QSA]
RewriteRule ^products/([\d,]+)/?$ index.php?resource=products&id=$1 [L,QSA]
RewriteRule ^categories/(\d+)/products/?$ index.php?resource=products&category=$1 [L,QSA]
RewriteRule ^categories/(\d+)/brands/(\d+)/products/?$ index.php?resource=products&category=$1&category=$2 [L,QSA]
RewriteRule ^categories/?$ index.php?resource=categories [L,QSA]
RewriteRule ^products/(\d+)/categories/?$ index.php?resource=products_categories&product_id=$1 [L,QSA]
RewriteRule ^orders/(\d+)/purchases/?$ index.php?resource=purchases&order_id=$1 [L,QSA]
# Blog
RewriteRule ^blog/?$ index.php?resource=blog [L,QSA]
RewriteRule ^blog/([\d,]+)/?$ index.php?resource=blog&id=$1 [L,QSA]
# Orders
RewriteRule ^orders/?$ index.php?resource=orders [L,QSA]
RewriteRule ^orders/([\d,]+)/?$ index.php?resource=orders&id=$1 [L,QSA]

9
simpla/rest/Rest.php Normal file
View File

@@ -0,0 +1,9 @@
<?php
require_once('api/Simpla.php');
class Rest extends Simpla
{
}

130
simpla/rest/RestBlog.php Normal file
View File

@@ -0,0 +1,130 @@
<?php
/**
* Simpla CMS
*
* @copyright 2012 Denis Pikusov
* @link http://simplacms.ru
* @author Denis Pikusov
*
*/
require_once('Rest.php');
class RestBlog extends Rest
{
public function fetch()
{
if($this->request->method('GET'))
$result = $this->get();
if($this->request->method('POST'))
$result = $this->post();
if($this->request->method('PUT'))
$result = $this->put();
if($this->request->method('DELETE'))
$result = $this->delete();
return $this->indent(json_encode($result));
}
public function get()
{
$fields = explode(',', $this->request->get('fields'));
$ids = array();
foreach(explode(',', $this->request->get('id')) as $id)
if(($id = intval($id))>0)
$ids[] = $id;
$filter = array();
if(!empty($ids))
$filter['id'] = $ids;
$filter['sort'] = $this->request->get('sort');
$filter['category_id'] = $this->request->get('category_id');
$filter['page'] = $this->request->get('page');
$filter['limit'] = $this->request->get('limit');
$products = array();
foreach($this->blog->get_posts($filter) as $p)
{
$products[$p->id] = null;
if($this->request->get('fields'))
foreach($fields as $field)
{
if(isset($p->$field))
$products[$p->id]->$field = $p->$field;
}
else
$products[$p->id] = $p;
}
$products_ids = array_keys($products);
if($join = $this->request->get('join'))
{
$join = explode(',', $join);
if(in_array('images', $join))
{
foreach($this->products->get_images(array('product_id'=>$products_ids)) as $i)
if(isset($products[$i->product_id]))
{
$products[$i->product_id]->images[$i->id] = $i;
}
}
if(in_array('variants', $join))
{
foreach($this->variants->get_variants(array('product_id'=>$products_ids)) as $v)
if(isset($products[$v->product_id]))
$products[$v->product_id]->variants[$v->id] = $v;
}
if(in_array('categories', $join))
{
foreach($this->categories->get_products_categories(array('product_id'=>$products_ids)) as $pc)
{
if(isset($products[$pc->product_id]))
{
$products[$pc->product_id]["categories"][$pc->category_id] = $pc;
$products[$pc->product_id]["categories"][$pc->category_id]->category = $this->categories->get_category(intval($pc->category_id));
}
}
}
}
return $products;
}
public function post_product()
{
if($this->request->method('POST'))
{
$product = json_decode($this->request->post());
$variants = $product->variants;
unset($product->variants);
$id = $this->products->add_product($product);
if(!empty($variants))
{
foreach($variants as $v)
{
$v->product_id = $id;
$varinat_id = $this->variants->add_variant($v);
}
}
if(!$id)
return false;
}
header("Content-type: application/json");
header("Location: ".$this->config->root_url."/simpla/rest/products/".$id, true, 201);
}
// Создать товар
public function put_product()
{
}
}

View File

@@ -0,0 +1,130 @@
<?php
/**
* Simpla CMS
*
* @copyright 2012 Denis Pikusov
* @link http://simplacms.ru
* @author Denis Pikusov
*
*/
require_once('Rest.php');
class RestBlog extends Rest
{
public function fetch()
{
if($this->request->method('GET'))
$result = $this->get();
if($this->request->method('POST'))
$result = $this->post();
if($this->request->method('PUT'))
$result = $this->put();
if($this->request->method('DELETE'))
$result = $this->delete();
return $this->indent(json_encode($result));
}
public function get()
{
$fields = explode(',', $this->request->get('fields'));
$ids = array();
foreach(explode(',', $this->request->get('id')) as $id)
if(($id = intval($id))>0)
$ids[] = $id;
$filter = array();
if(!empty($ids))
$filter['id'] = $ids;
$filter['sort'] = $this->request->get('sort');
$filter['category_id'] = $this->request->get('category_id');
$filter['page'] = $this->request->get('page');
$filter['limit'] = $this->request->get('limit');
$products = array();
foreach($this->blog->get_posts($filter) as $p)
{
$products[$p->id] = null;
if($this->request->get('fields'))
foreach($fields as $field)
{
if(isset($p->$field))
$products[$p->id]->$field = $p->$field;
}
else
$products[$p->id] = $p;
}
$products_ids = array_keys($products);
if($join = $this->request->get('join'))
{
$join = explode(',', $join);
if(in_array('images', $join))
{
foreach($this->products->get_images(array('product_id'=>$products_ids)) as $i)
if(isset($products[$i->product_id]))
{
$products[$i->product_id]->images[$i->id] = $i;
}
}
if(in_array('variants', $join))
{
foreach($this->variants->get_variants(array('product_id'=>$products_ids)) as $v)
if(isset($products[$v->product_id]))
$products[$v->product_id]->variants[$v->id] = $v;
}
if(in_array('categories', $join))
{
foreach($this->categories->get_products_categories(array('product_id'=>$products_ids)) as $pc)
{
if(isset($products[$pc->product_id]))
{
$products[$pc->product_id]["categories"][$pc->category_id] = $pc;
$products[$pc->product_id]["categories"][$pc->category_id]->category = $this->categories->get_category(intval($pc->category_id));
}
}
}
}
return $products;
}
public function post_product()
{
if($this->request->method('POST'))
{
$product = json_decode($this->request->post());
$variants = $product->variants;
unset($product->variants);
$id = $this->products->add_product($product);
if(!empty($variants))
{
foreach($variants as $v)
{
$v->product_id = $id;
$varinat_id = $this->variants->add_variant($v);
}
}
if(!$id)
return false;
}
header("Content-type: application/json");
header("Location: ".$this->config->root_url."/simpla/rest/products/".$id, true, 201);
}
// Создать товар
public function put_product()
{
}
}

View File

@@ -0,0 +1,67 @@
<?php
/**
* Simpla CMS
*
* @copyright 2012 Denis Pikusov
* @link http://simplacms.ru
* @author Denis Pikusov
*
*/
require_once('Rest.php');
class RestOrders extends Rest
{
public function get()
{
$items = array();
$filter = array();
// id
$filter['id'] = $this->request->get('id');
// Сортировка
$filter['status'] = $this->request->get('status');
// Страница
$filter['page'] = $this->request->get('page');
// Количество элементов на странице
$filter['limit'] = $this->request->get('limit');
// Какие поля отдавать
if($fields = $this->request->get('fields'))
$fields = explode(',', $fields);
// Выбираем
foreach($this->orders->get_orders($filter) as $item)
{
$items[$item->id] = new stdClass();
if($fields)
{
foreach($fields as $field)
if(isset($item->$field))
$items[$item->id]->$field = $item->$field;
}
else
$items[$item->id] = $item;
}
if(empty($items))
return false;
// Выбранные id
$items_ids = array_keys($items);
// Присоединяемые данные
if($join = $this->request->get('join'))
{
$join = explode(',', $join);
// Изображения
if(in_array('purchases', $join))
{
foreach($this->orders->get_purchases(array('order_id'=>$items_ids)) as $i)
if(isset($items[$i->order_id]))
$items[$i->order_id]->purchases[] = $i;
}
}
return array_values($items);
}
}

View File

@@ -0,0 +1,198 @@
<?php
/**
* Simpla CMS
*
* @copyright 2012 Denis Pikusov
* @link http://simplacms.ru
* @author Denis Pikusov
*
*/
require_once('Rest.php');
class RestProducts extends Rest
{
public function get()
{
$items = array();
$filter = array();
// id
$filter['id'] = array();
foreach(explode(',', $this->request->get('id')) as $id)
if(($id = intval($id)) > 0)
$filter['id'][] = $id;
// Сортировка
$filter['sort'] = $this->request->get('sort');
// Категория
$filter['category_id'] = $this->request->get('category');
// Дата последнего изменения
$filter['modified_from'] = $this->request->get('modified_from');
// Бренд
$filter['brand_id'] = $this->request->get('brand');
// Страница
$filter['page'] = $this->request->get('page');
// Количество элементов на странице
$filter['limit'] = $this->request->get('limit');
// Какие поля отдавать
if($fields = $this->request->get('fields'))
$fields = explode(',', $fields);
// Выбираем
foreach($this->products->get_products($filter) as $item)
{
$items[$item->id] = new stdClass();
if($fields)
{
foreach($fields as $field)
if(isset($item->$field))
$items[$item->id]->$field = $item->$field;
}
else
$items[$item->id] = $item;
}
if(empty($items))
return false;
// Выбранные id
$items_ids = array_keys($items);
// Присоединяемые данные
if($join = $this->request->get('join'))
{
$join = explode(',', $join);
// Изображения
if(in_array('images', $join))
{
foreach($this->products->get_images(array('product_id'=>$items_ids)) as $i)
if(isset($items[$i->product_id]))
$items[$i->product_id]->images[] = $i;
}
// Варианты
if(in_array('variants', $join))
{
foreach($this->variants->get_variants(array('product_id'=>$items_ids)) as $v)
if(isset($items[$v->product_id]))
$items[$v->product_id]->variants[] = $v;
}
// Категории
$categories_ids = array();
if(in_array('categories', $join))
{
foreach($this->categories->get_products_categories(array('product_id'=>$items_ids)) as $pc)
{
if(isset($items[$pc->product_id]))
{
$c = $pc;
$c = $this->categories->get_category(intval($pc->category_id));
unset($c->path);
unset($c->subcategories);
unset($c->children);
$items[$pc->product_id]->categories[] = $c;
$categories_ids[] = $pc->category_id;
}
}
}
// Свойства
if(in_array('features', $join))
{
$features_ids = array();
foreach($this->features->get_options(array('product_id'=>$items_ids)) as $o)
{
if(isset($items[$o->product_id]))
{
$options[$o->feature_id] = $o;
$features_ids[] = $o->feature_id;
}
}
foreach($this->features->get_features(array('id'=>$features_ids)) as $f)
{
if(isset($options[$f->id]))
{
$f->value = $o->value;
$items[$o->product_id]->features[] = $f;
}
}
}
}
return array_values($items);
}
public function post()
{
$product = json_decode($this->request->post());
print_r($product);
$variants = $product->variants;
unset($product->variants);
$id = $this->products->add_product($product);
if(!empty($variants))
{
foreach($variants as $v)
{
$v->product_id = $id;
$varinat_id = $this->variants->add_variant($v);
}
}
if(!$id)
return false;
else
return $id;
header("Content-type: application/json");
header("Location: ".$this->config->root_url."/simpla/rest/products/".$id, true, 201);
}
public function put()
{
$id = intval($this->request->get('id'));
if(empty($id) || !$this->products->get_product($id))
{
header("HTTP/1.0 404 Not Found");
exit();
}
$product = json_decode($this->request->post());
$variants = $product->variants;
unset($product->variants);
$id = $this->products->update_product($id, $product);
if(!empty($variants))
{
$variants_ids = array();
foreach($variants as $v)
{
$v->product_id = $id;
if($v->stock == '∞' || $v->stock == '')
$v->stock = null;
if($v->id)
$this->variants->update_variant($v->id, $v);
else
{
$v->product_id = $id;
$v->id = $this->variants->add_variant($v);
}
$variants_ids[] = $v->id;
// Удалить непереданные варианты
$current_variants = $this->variants->get_variants(array('product_id'=>$id));
foreach($current_variants as $current_variant)
if(!in_array($current_variant->id, $variants_ids))
$this->variants->delete_variant($current_variant->id);
}
}
if(!$id)
return false;
else
return $id;
header("Content-type: application/json");
header("Location: ".$this->config->root_url."/simpla/rest/products/".$id, true, 201);
}
}

325
simpla/rest/example.php Normal file
View File

@@ -0,0 +1,325 @@
<?php
if($_SERVER['REQUEST_METHOD'] == 'POST')
{
$data = str_replace('\n', '', $_POST['body']);
$data = str_replace(' ', '', $data);
$data = stripslashes($data);
$request = new RestRequest($_POST['url'], $_POST['method'], $data);
$request->setUsername('qwe');
$request->setPassword('qwe');
$request->execute();
}
?><!DOCTYPE html>
<html>
<head>
<title>REST API demo</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<h1>REST API demo</h1>
<form method="post">
<p>
<labe>Method</label><br>
<select name="method">
<option value="GET" <?php if(isset($_POST['method']) && $_POST['method'] == 'GET') print "selected"; ?>>GET</option>
<option value="PUT" <?php if(isset($_POST['method']) && $_POST['method'] == 'PUT') print "selected"; ?>>PUT</option>
<option value="POST" <?php if(isset($_POST['method']) && $_POST['method'] == 'POST') print "selected"; ?>>POST</option>
<option value="DELETE" <?php if(isset($_POST['method']) && $_POST['method'] == 'DELETE') print "selected"; ?>>DELETE</option>
</select>
</p>
<p>
<labe>URL</label><br>
<input type="text" size="100" name="url" value="<?php if(isset($_POST['url']))print $_POST['url']; else print "http://simpla".dirname($_SERVER['REQUEST_URI'])."/products/"; ?>">
</p>
<p>
<labe>Body:</label><br>
<textarea cols="100" rows="20" name="body"><?php if(isset($_POST['body'])) print stripslashes($_POST['body']) ?></textarea><br>
<input type="submit" value="Send">
</p>
<p>
<labe>Response:</label><br>
<textarea cols="100" rows="20" name="response"><?php if(is_object($request)) print stripslashes(indent($request->getResponseBody())); ?></textarea>
</p>
<p>
<labe>Response Info:</label><br>
<textarea cols="100" rows="20" name="response_info"><?php if(is_object($request)){ $info = $request->getResponseInfo(); stripslashes(print_r($info)); }?></textarea>
</p>
</form>
</body>
</html>
<?php
class RestRequest
{
protected $url;
protected $verb;
protected $requestBody;
protected $requestLength;
protected $username;
protected $password;
protected $acceptType;
protected $responseBody;
protected $responseInfo;
public function __construct ($url = null, $verb = 'GET', $requestBody = null)
{
$this->url = $url;
$this->verb = $verb;
$this->requestBody = $requestBody;
$this->requestLength = 0;
$this->username = null;
$this->password = null;
$this->acceptType = 'application/json';
$this->responseBody = null;
$this->responseInfo = null;
if ($this->requestBody !== null)
{
$this->buildPostBody();
}
}
public function flush ()
{
$this->requestBody = null;
$this->requestLength = 0;
$this->verb = 'GET';
$this->responseBody = null;
$this->responseInfo = null;
}
public function execute ()
{
$ch = curl_init();
$this->setAuth($ch);
try
{
switch (strtoupper($this->verb))
{
case 'GET':
$this->executeGet($ch);
break;
case 'POST':
$this->executePost($ch);
break;
case 'PUT':
$this->executePut($ch);
break;
case 'DELETE':
$this->executeDelete($ch);
break;
default:
throw new InvalidArgumentException('Current verb (' . $this->verb . ') is an invalid REST verb.');
}
}
catch (InvalidArgumentException $e)
{
curl_close($ch);
throw $e;
}
catch (Exception $e)
{
curl_close($ch);
throw $e;
}
}
public function buildPostBody ($data = null)
{
$data = ($data !== null) ? $data : $this->requestBody;
$this->requestBody = $data;
}
protected function executeGet ($ch)
{
$this->doExecute($ch);
}
protected function executePost ($ch)
{
if (!is_string($this->requestBody))
{
$this->buildPostBody();
}
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->requestBody);
curl_setopt($ch, CURLOPT_POST, 1);
$this->doExecute($ch);
}
protected function executePut ($ch)
{
if (!is_string($this->requestBody))
{
$this->buildPostBody();
}
$this->requestLength = strlen($this->requestBody);
$fh = fopen('php://memory', 'rw');
fwrite($fh, $this->requestBody);
rewind($fh);
curl_setopt($ch, CURLOPT_PATHINFO, $fh);
curl_setopt($ch, CURLOPT_INFILE, $fh);
curl_setopt($ch, CURLOPT_INFILESIZE, $this->requestLength);
curl_setopt($ch, CURLOPT_PUT, true);
$this->doExecute($ch);
fclose($fh);
}
protected function executeDelete ($ch)
{
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
$this->doExecute($ch);
}
protected function doExecute (&$curlHandle)
{
$this->setCurlOpts($curlHandle);
$this->responseBody = curl_exec($curlHandle);
$this->responseInfo = curl_getinfo($curlHandle);
curl_close($curlHandle);
}
protected function setCurlOpts (&$curlHandle)
{
curl_setopt($curlHandle, CURLOPT_TIMEOUT, 10);
curl_setopt($curlHandle, CURLOPT_URL, $this->url);
curl_setopt($curlHandle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curlHandle, CURLOPT_HTTPHEADER, array ('Accept: ' . $this->acceptType));
}
protected function setAuth (&$curlHandle)
{
if ($this->username !== null && $this->password !== null)
{
curl_setopt($curlHandle, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curlHandle, CURLOPT_USERPWD, $this->username . ':' . $this->password);
}
}
public function getAcceptType ()
{
return $this->acceptType;
}
public function setAcceptType ($acceptType)
{
$this->acceptType = $acceptType;
}
public function getPassword ()
{
return $this->password;
}
public function setPassword ($password)
{
$this->password = $password;
}
public function getResponseBody ()
{
return $this->responseBody;
}
public function getResponseInfo ()
{
return $this->responseInfo;
}
public function getUrl ()
{
return $this->url;
}
public function setUrl ($url)
{
$this->url = $url;
}
public function getUsername ()
{
return $this->username;
}
public function setUsername ($username)
{
$this->username = $username;
}
public function getVerb ()
{
return $this->verb;
}
public function setVerb ($verb)
{
$this->verb = $verb;
}
}
function indent($json) {
$result = '';
$pos = 0;
$strLen = strlen($json);
$indentStr = ' ';
$newLine = "\n";
$prevChar = '';
$outOfQuotes = true;
for ($i=0; $i<=$strLen; $i++) {
// Grab the next character in the string.
$char = substr($json, $i, 1);
// Are we inside a quoted string?
if ($char == '"' && $prevChar != '\\') {
$outOfQuotes = !$outOfQuotes;
// If this character is the end of an element,
// output a new line and indent the next line.
} else if(($char == '}' || $char == ']') && $outOfQuotes) {
$result .= $newLine;
$pos --;
for ($j=0; $j<$pos; $j++) {
$result .= $indentStr;
}
}
// Add the character to the result string.
$result .= $char;
// If the last character was the beginning of an element,
// output a new line and indent the next line.
if (($char == ',' || $char == '{' || $char == '[') && $outOfQuotes) {
$result .= $newLine;
if ($char == '{' || $char == '[') {
$pos ++;
}
for ($j = 0; $j < $pos; $j++) {
$result .= $indentStr;
}
}
$prevChar = $char;
}
return $result;
}

Some files were not shown because too many files have changed in this diff Show More