PageRenderTime 48ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/shop/classes/model/frontend/categories.php

https://bitbucket.org/seyar/ari100krat.local
PHP | 939 lines | 936 code | 3 blank | 0 comment | 0 complexity | fbaba4e4386dd71dfffa5b8f914dd99b MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.1
  1. <?php
  2. defined( 'SYSPATH' ) OR die( 'No direct access allowed.' );
  3. class Model_Frontend_Categories extends Model
  4. {
  5. protected static $recursion_return;
  6. static private $_filtableFields = null;
  7. static private $_categoryId = null;
  8. static public $url_search = array( '%23', '%3F', '%2F', '%26', '.', ',', 'quot','amp', '/','"',"'",'%27',';','%2C','%28','%29','%3B','&','%2B','(',')', );
  9. static public $url_replace = array( '', '', '', '', '', '','_','_','_', '', '','','','','(',')','','','','','' );
  10. static public function info( $id = NULL )
  11. {
  12. $query = Db::select( 'id', 'name','parent_id', 'page_title', 'display_mode', 'parents_serialized', 'description', 'seo_url' )
  13. ->from( 'shop_categories' )
  14. ->where( 'id', '=', $id )
  15. ->and_where( 'status', '=', 'verified' )
  16. ;
  17. $result = $query->execute();
  18. if( $result->count() == 0 )
  19. return array( );
  20. else
  21. {
  22. $return = array( );
  23. $return = $result->current();
  24. $return['parents_serialized'] = unserialize( $return['parents_serialized'] );
  25. return $return;
  26. }
  27. }
  28. static public function init()
  29. {
  30. Kohana_Controller_Quicky::$intermediate_vars['shop_top_categories'] =
  31. Model_Frontend_Categories::show_categories( Kohana::config( 'shop' )->root_category_id );
  32. Kohana_Controller_Quicky::$intermediate_vars['shop_config'] = (array) Kohana::config( 'shop' );
  33. }
  34. static public function show_categories( $parent_id = NULL )
  35. {
  36. $query = Db::query( Database::SELECT, "SELECT c.`id`, c.`name`, c.`seo_url` AS category_url, c.`display_mode`, c1.parent_id AS `count` "
  37. . " FROM `shop_categories` AS c"
  38. . " LEFT JOIN (SELECT DISTINCT c2.parent_id FROM shop_categories AS c2 ) AS c1 ON (c.id = c1.parent_id) "
  39. . " WHERE c.`languages_id` = " . CURRENT_LANG_ID
  40. . " AND c.`parent_id` = $parent_id "
  41. . " AND c.`status` = 'verified' "
  42. . " ORDER BY c.`order_id` ASC, c.name ASC"
  43. )
  44. ->cached( 60 );
  45. $result = $query->execute();
  46. if( $result->count() == 0 )
  47. return array( );
  48. else
  49. {
  50. $return = array( );
  51. foreach( $result->as_array( 'id' ) as $key => $val )
  52. {
  53. $val['category_url'] = $val['category_url'] ? $val['category_url'] : Controller_Admin::to_url( $val['name'] );
  54. $return[$key] = $val;
  55. }
  56. return $return;
  57. }
  58. }
  59. static public function show_child_categories( $category_id = NULL )
  60. {
  61. $return = array( );
  62. $result = Model_Frontend_Categories::child_categories( $category_id );
  63. foreach( $result as $key => $val )
  64. {
  65. if( $val['name'] )
  66. $val['category_url'] = $val['category_url'] ? $val['category_url'] : Controller_Admin::to_url( $val['name'] );
  67. $return[$key] = $val;
  68. }
  69. return $return['childs'];
  70. }
  71. static public function show_bestseller( $limit = NULL, $price_category = NULL )
  72. {
  73. $query = Db::select( 'g.*'
  74. , array( 'c.name', 'category_name' )
  75. , array( 'c.seo_url', 'category_url' )
  76. , array( 'c.page_title', 'page_title' )
  77. )
  78. ->from( array( 'shop_goods', 'g' ))
  79. ->join( array( 'shop_categories', 'c' ))
  80. ->on( 'g.categories_id', '=', 'c.id' )
  81. ->join( array( 'shop_prices', 'z' ) )
  82. // ->on('z.good_id' , '=', 'c.id')
  83. // ->on('z.good_id' , '=', 'g.categories_id')
  84. // ->on('c.id', '=', 'z.good_id')
  85. // ->on('g.categories_id' , '=', 'z.good_id')
  86. ->on( 'g.id', '=', 'z.good_id' )
  87. ->where( 'z.price', '>', '0' )
  88. ->where( 'z.price_categories_id', '=', $price_category )
  89. ->and_where( 'c.languages_id', '=', CURRENT_LANG_ID )
  90. // ->or_where( 'g.status', '=', 'from1c' )
  91. ->where( 'g.is_bestseller', '>', '0' )
  92. ->order_by( 'g.name' )
  93. ->cached( 180 )
  94. ;
  95. $query->and_where_open();
  96. foreach( Kohana::config('shop.frontendStatuses') as $key => $item )
  97. {
  98. $query->or_where( "g.status", '=', $item );
  99. }
  100. $query->and_where_close();
  101. if( is_numeric( $limit ) )
  102. $query->limit( (int) $limit );
  103. $result = $query->execute();
  104. if( $result->count() == 0 )
  105. return array( );
  106. else
  107. {
  108. $return = array( );
  109. $tmpkeys = $result->as_array( 'id' );
  110. $rows = Model_Frontend_Goods::getPriceCategories( array_keys($tmpkeys), $price_category );
  111. $curr = new Model_Frontend_Currencies();
  112. foreach( $tmpkeys as $key => $val )
  113. {
  114. $prices = array( );
  115. // foreach ($rows as $value)
  116. // {
  117. // $prices[$value['price_categories_id']][$value['currencies_id']] = $value['price'];
  118. // }
  119. //
  120. // $val['prices'] = $prices;
  121. if( $val['quantity'] == 0 )
  122. $val['store_approximate_date'] = Model_Frontend_Goods::getApproximateDate( $val['store_approximate_date'] );
  123. $val['prices'] = $curr->getPrice( $rows[$key] );
  124. $val['seo_url'] = $val['seo_url'] ? str_replace( self::$url_search, self::$url_replace, urlencode($val['seo_url']) ) : str_replace( self::$url_search, self::$url_replace, Controller_Admin::to_url( $val['name'] ));
  125. $val['seo_url'] = str_replace( '__', '_', $val['seo_url'] );
  126. $val['seo_url'] = str_replace( '__', '_', $val['seo_url'] );
  127. $val['category_url'] = $val['category_url'] ? str_replace( self::$url_search, self::$url_replace, urlencode( $val['category_url'] ) ) : str_replace( self::$url_search, self::$url_replace, Controller_Admin::to_url( $val['category_name'] ));
  128. $val['category_url'] = str_replace( '__', '_', $val['category_url'] );
  129. $val['category_url'] = str_replace( '__', '_', $val['category_url'] );
  130. $return[$key] = $val;
  131. }
  132. return $return;
  133. }
  134. }
  135. static public function show_last( $limit = NULL, $price_categoty = null )
  136. {
  137. $query = Db::select( 'g.*', array( 'c.name', 'category_name' ), array( 'c.seo_url', 'category_url' ) )
  138. ->from( array( 'shop_goods', 'g' ) )
  139. ->join( array( 'shop_categories', 'c' ) )
  140. ->on( 'g.categories_id', '=', 'c.id' )
  141. ->join( array( 'shop_categories', 'c1' ) )
  142. ->on( 'c.parent_id', '=', 'c1.id' )
  143. ->where( 'c.languages_id', '=', CURRENT_LANG_ID )
  144. ->where( 'c.status', '=', 'verified' )
  145. ->where( 'c1.status', '=', 'verified' )
  146. ->order_by( 'g.id', 'desc' )
  147. ->cached( 180 )
  148. ;
  149. $query->and_where_open();
  150. foreach( Kohana::config('shop.frontendStatuses') as $key => $item )
  151. {
  152. $query->or_where( "g.status", '=', $item );
  153. }
  154. $query->and_where_close();
  155. if( is_numeric( $limit ) )
  156. $query->limit( (int) $limit );
  157. $result = $query->execute();
  158. if( $result->count() == 0 )
  159. return array( );
  160. else
  161. {
  162. $return = array( );
  163. $curr = new Model_Frontend_Currencies();
  164. foreach( $result->as_array( 'id' ) as $key => $val )
  165. {
  166. $query = Db::select( 'p.price_categories_id', 'p.currencies_id', 'p.price' )
  167. ->from( array( 'shop_prices', 'p' ) )
  168. ->where( 'p.good_id', '=', $key )
  169. ->order_by( 'p.currencies_id' )
  170. ->cached( 60 )
  171. ;
  172. if( is_numeric( $price_categoty ) )
  173. $query->where( 'p.price_categories_id', '=', (int) $price_categoty );
  174. $prices = array( );
  175. $rows = $query->execute()->as_array();
  176. if( $val['quantity'] == 0 )
  177. $val['store_approximate_date'] = Model_Frontend_Goods::getApproximateDate( $val['store_approximate_date'] );
  178. $val['prices'] = $curr->getPrice( $rows );
  179. $val['seo_url'] = $val['seo_url'] ? str_replace( self::$url_search, self::$url_replace, urlencode($val['seo_url']) ) : str_replace( self::$url_search, self::$url_replace, Controller_Admin::to_url( $val['name'] ));
  180. $val['seo_url'] = str_replace( '__', '_', $val['seo_url'] );
  181. $val['seo_url'] = str_replace( '__', '_', $val['seo_url'] );
  182. $val['category_url'] = $val['category_url'] ? str_replace( self::$url_search, self::$url_replace, urlencode( $val['category_url'] ) ) : str_replace( self::$url_search, self::$url_replace, Controller_Admin::to_url( $val['category_name'] ));
  183. $val['category_url'] = str_replace( '__', '_', $val['category_url'] );
  184. $val['category_url'] = str_replace( '__', '_', $val['category_url'] );
  185. $return[$key] = $val;
  186. }
  187. return $return;
  188. }
  189. }
  190. static public function show_new( $limit = NULL, $price_categoty = NULL )
  191. {
  192. $query = Db::select( 'g.*', array( 'c.name', 'category_name' ), array( 'c.seo_url', 'category_url' ) )
  193. ->from( array( 'shop_goods', 'g' ) )
  194. ->join( array( 'shop_categories', 'c' ) )
  195. ->on( 'g.categories_id', '=', 'c.id' )
  196. ->join( array( 'shop_categories', 'c1' ) )
  197. ->on( 'c.parent_id', '=', 'c1.id' )
  198. ->where( 'c.languages_id', '=', CURRENT_LANG_ID )
  199. ->where( 'g.is_new', '>', '0' )
  200. ->where( 'c.status', '=', 'verified' )
  201. ->where( 'c1.status', '=', 'verified' )
  202. ->order_by( 'g.name' )
  203. ->cached( 180 )
  204. ;
  205. $query->and_where_open();
  206. foreach( Kohana::config('shop.frontendStatuses') as $key => $item )
  207. {
  208. $query->or_where( "g.status", '=', $item );
  209. }
  210. $query->and_where_close();
  211. if( is_numeric( $limit ) )
  212. $query->limit( (int) $limit );
  213. $result = $query->execute();
  214. if( $result->count() == 0 )
  215. return array( );
  216. else
  217. {
  218. $return = array( );
  219. $curr = new Model_Frontend_Currencies();
  220. foreach( $result->as_array( 'id' ) as $key => $val )
  221. {
  222. $query = Db::select( 'p.price_categories_id', 'p.currencies_id', 'p.price' )
  223. ->from( array( 'shop_prices', 'p' ) )
  224. ->where( 'p.good_id', '=', $key )
  225. ->order_by( 'p.currencies_id' )
  226. ->cached( 60 )
  227. ;
  228. if( is_numeric( $price_categoty ) )
  229. $query->where( 'p.price_categories_id', '=', (int) $price_categoty );
  230. $prices = array( );
  231. $rows = $query->execute()->as_array();
  232. // foreach ($rows as $value)
  233. // {
  234. // $prices[$value['price_categories_id']][$value['currencies_id']] = $value['price'];
  235. // }
  236. //
  237. // $val['prices'] = $prices;
  238. if( $val['quantity'] == 0 )
  239. $val['store_approximate_date'] = Model_Frontend_Goods::getApproximateDate( $val['store_approximate_date'] );
  240. $val['prices'] = $curr->getPrice( $rows );
  241. $val['seo_url'] = $val['seo_url'] ? str_replace( self::$url_search, self::$url_replace, urlencode( $val['seo_url'] ) ) : str_replace( self::$url_search, self::$url_replace, Controller_Admin::to_url( $val['name'] ));
  242. $val['seo_url'] = str_replace( '__', '_', $val['seo_url'] );
  243. $val['seo_url'] = str_replace( '__', '_', $val['seo_url'] );
  244. $val['category_url'] = $val['category_url'] ? str_replace( self::$url_search, self::$url_replace, urlencode( $val['category_url'] ) ) : str_replace( self::$url_search, self::$url_replace, Controller_Admin::to_url( $val['category_name'] ));
  245. $val['category_url'] = str_replace( '__', '_', $val['category_url'] );
  246. $val['category_url'] = str_replace( '__', '_', $val['category_url'] );
  247. $return[$key] = $val;
  248. }
  249. return $return;
  250. }
  251. }
  252. static public function show_onstartpage( $limit = NULL, $price_categoty = NULL )
  253. {
  254. $query = Db::select( 'g.*', array( 'c.name', 'category_name' ), array( 'c.seo_url', 'category_url' ) )
  255. ->from( array( 'shop_goods', 'g' ) )
  256. ->join( array( 'shop_categories', 'c' ) )
  257. ->on( 'g.categories_id', '=', 'c.id' )
  258. ->join( array( 'shop_categories', 'c1' ) )
  259. ->on( 'c.parent_id', '=', 'c1.id' )
  260. ->where( 'c.languages_id', '=', CURRENT_LANG_ID )
  261. ->where( 'g.show_on_startpage', '=', '1' )
  262. ->where( 'c.status', '=', 'verified' )
  263. ->where( 'c1.status', '=', 'verified' )
  264. ->order_by( 'g.name' )
  265. ->cached( 180 )
  266. ;
  267. $query->and_where_open();
  268. foreach( Kohana::config('shop.frontendStatuses') as $key => $item )
  269. {
  270. $query->or_where( "g.status", '=', $item );
  271. }
  272. $query->and_where_close();
  273. if( is_numeric( $limit ) )
  274. $query->limit( (int) $limit );
  275. $result = $query->execute();
  276. if( $result->count() == 0 )
  277. return array( );
  278. else
  279. {
  280. $return = array( );
  281. $curr = new Model_Frontend_Currencies();
  282. foreach( $result->as_array( 'id' ) as $key => $val )
  283. {
  284. $query = Db::select( 'p.price_categories_id', 'p.currencies_id', 'p.price' )
  285. ->from( array( 'shop_prices', 'p' ) )
  286. ->where( 'p.good_id', '=', $key )
  287. ->order_by( 'p.currencies_id' )
  288. ->cached( 60 )
  289. ;
  290. if( is_numeric( $price_categoty ) )
  291. $query->where( 'p.price_categories_id', '=', (int) $price_categoty );
  292. $prices = array( );
  293. $rows = $query->execute()->as_array();
  294. // foreach ($rows as $value)
  295. // {
  296. // $prices[$value['price_categories_id']][$value['currencies_id']] = $value['price'];
  297. // }
  298. //
  299. // $val['prices'] = $prices;
  300. if( $val['quantity'] == 0 )
  301. $val['store_approximate_date'] = Model_Frontend_Goods::getApproximateDate( $val['store_approximate_date'] );
  302. $val['prices'] = $curr->getPrice( $rows );
  303. $val['seo_url'] = $val['seo_url'] ? str_replace( self::$url_search, self::$url_replace, urlencode( $val['seo_url'] ) ) : str_replace( self::$url_search, self::$url_replace, Controller_Admin::to_url( $val['name'] ));
  304. $val['seo_url'] = str_replace( '__', '_', $val['seo_url'] );
  305. $val['seo_url'] = str_replace( '__', '_', $val['seo_url'] );
  306. $val['category_url'] = $val['category_url'] ? str_replace( self::$url_search, self::$url_replace, urlencode( $val['category_url'] ) ) : str_replace( self::$url_search, self::$url_replace, Controller_Admin::to_url( $val['category_name'] ));
  307. $val['category_url'] = str_replace( '__', '_', $val['category_url'] );
  308. $val['category_url'] = str_replace( '__', '_', $val['category_url'] );
  309. $return[$key] = $val;
  310. }
  311. return $return;
  312. }
  313. }
  314. static protected function find_last_childrens( $param_id, &$param_rows, $parents_info_array=array( ) )
  315. {
  316. $p_return = array( );
  317. foreach( $param_rows as $p_k => $p_v )
  318. {
  319. if( $p_v['parent_id'] == $param_id )
  320. {
  321. $parents_info_array = array( 'id' => $p_v['id'], 'name' => $p_v['name'] ); // save object depth
  322. $p_return[$param_id][$p_v['id']] = $p_v;
  323. foreach( Model_Frontend_Categories::find_last_childrens( $p_v['id'], $param_rows, $parents_info_array ) AS $value )
  324. {
  325. $p_return[$param_id][$p_v['id']]['childs'] = $value;
  326. }
  327. $p_return[$param_id][$p_v['id']]['parents_info'] = $parents_info_array;
  328. array_pop( $parents_info_array );
  329. }
  330. }
  331. return $p_return;
  332. }
  333. static public function child_categories( $category_id = NULL, $lang_id = 1 )
  334. {
  335. $return = array( Kohana::config( 'shop' )
  336. ->root_category_id => array( 'name' => I18n::get( 'Root Category' ), 'id' => Kohana::config( 'shop' )->root_category_id ) );
  337. $query = DB::select( 'id', 'name', 'parent_id', 'seo_url' )
  338. ->from( 'shop_categories' )
  339. ->where( 'languages_id', '=', $lang_id )
  340. ->and_where( 'status', '=', 'verified' )
  341. ->order_by( 'order_id' )
  342. ->order_by( 'name' )
  343. ->cached( 10 );
  344. $result = $query->execute(); //->cached(10)
  345. if( $result->count() == 0 )
  346. return $return;
  347. else
  348. {
  349. $rows = $result->as_array( 'id' );
  350. $rows = self::find_last_childrens( Kohana::config( 'shop' )->root_category_id, $rows, false );
  351. if( isset($category_id) )
  352. return $rows[Kohana::config( 'shop' )->root_category_id][$category_id];
  353. else
  354. return $rows[Kohana::config( 'shop' )->root_category_id];
  355. }
  356. }
  357. static function find_inner_categories( &$param_rows )
  358. {
  359. $p_return = array( );
  360. if( is_array( @$param_rows['childs'] ) )
  361. {
  362. foreach( $param_rows['childs'] as $p_k => $p_v )
  363. {
  364. $p_return[] = $p_k;
  365. foreach( Model_Frontend_Categories::find_inner_categories( $p_v['childs'] ) as $value )
  366. {
  367. $p_return[] = $value;
  368. }
  369. }
  370. }
  371. return $p_return;
  372. }
  373. static public function goods( $category_id = NULL, $rows_per_page = 10, $price_categoty = NULL, $filter = array( ), $sortby = null, $sortasc = 'asc', $brandId = null, $lang_id = 1 )
  374. {
  375. if( is_numeric( $category_id ) )
  376. {
  377. $curr = new Model_Frontend_Currencies();
  378. $price_categories_id = 1;
  379. $ids = array( );
  380. $rows = Model_Frontend_Categories::child_categories( $category_id );
  381. $childs = Model_Frontend_Categories::find_inner_categories( $rows );
  382. $query_c = DB::select( DB::expr( 'COUNT(*) AS mycount' ) )
  383. ->from( array( 'shop_goods', 'g' ) )
  384. ->join( array( 'shop_categories', 'c' ) )
  385. ->on( 'g.categories_id', '=', 'c.id' )
  386. ->join( array( DB::expr( '(select price,good_id from `shop_prices` where currencies_id = ' . $curr->getDefaultCurrency() . ' and price_categories_id = ' . $price_categories_id . ' group by good_id)' ), 'p' ), 'left outer' )
  387. ->on( 'p.good_id', '=', 'g.id' )
  388. //здесь дополнительное условие если цена больше 0
  389. ->where( 'p.price', '>', '0' )
  390. //конец
  391. ;
  392. $query_c->and_where_open();
  393. foreach( Kohana::config('shop.frontendStatuses') as $key => $item )
  394. {
  395. $query_c->or_where( "g.status", '=', $item );
  396. }
  397. $query_c->and_where_close();
  398. $query = Db::select( 'g.*', array( 'c.name', 'category_name' ), array( 'c.seo_url', 'category_url' ), array( 'p.price', 'price' ), array(DB::expr('IF(g.quantity > 0, 1, 0)'), 'exist') )
  399. ->from( array( 'shop_goods', 'g' ) )
  400. ->join( array( 'shop_categories', 'c' ) )
  401. ->on( 'g.categories_id', '=', 'c.id' )
  402. ->join( array( DB::expr( '(select price,good_id from `shop_prices` where currencies_id = ' . $curr->getDefaultCurrency() . ' and price_categories_id = ' . $price_categories_id . ' group by good_id)' ), 'p' ), 'left outer' )
  403. ->on( 'p.good_id', '=', 'g.id' )
  404. //здесь дополнительное условие если цена больше 0
  405. ->where( 'p.price', '>', '0' )
  406. //конец
  407. ->order_by( 'exist', 'desc' )
  408. ;
  409. $query->and_where_open();
  410. foreach( Kohana::config('shop.frontendStatuses') as $key => $item )
  411. {
  412. $query->or_where( "g.status", '=', $item );
  413. }
  414. $query->and_where_close();
  415. if( $brandId !== null )
  416. {
  417. $query_c->and_where( 'brand_id', '=', $brandId );
  418. $query->and_where( 'brand_id', '=', $brandId );
  419. }
  420. if( isset( $filter['add_fields'] ) )
  421. {
  422. $ids = self::getFilteredGoods( $filter['add_fields'] );
  423. if( empty( $ids ) )
  424. $ids = array( 0 );
  425. $query_c->and_where( 'g.id', 'in', DB::expr( "(" . implode( ",", $ids ) . ")" ) );
  426. $query->and_where( 'g.id', 'in', DB::expr( "(" . implode( ",", $ids ) . ")" ) );
  427. }
  428. $query_c->and_where_open()->where( 'g.categories_id', '=', $category_id );
  429. $query->and_where_open()->where( 'g.categories_id', '=', $category_id );
  430. if( count( $childs ) )
  431. foreach( $childs as $value )
  432. {
  433. $query_c->or_where( 'g.categories_id', '=', $value );
  434. $query->or_where( 'g.categories_id', '=', $value );
  435. }
  436. $query_c->and_where_close();
  437. $query->and_where_close();
  438. if( !self::validAsc( $sortasc ) )
  439. $sortasc = 'asc';
  440. if( strtolower($sortby) !== null && self::validSortableFields( $sortby ) )
  441. $query->order_by( $sortby, $sortasc );
  442. else
  443. $query->order_by( 'p.price', 'desc' );
  444. // echo Kohana::debug($query_c->__toString());
  445. $count = $query_c
  446. ->execute()
  447. ->get( 'mycount' );
  448. if( isset( $_POST['page'] ) )
  449. $_GET['page'] = $_POST['page'];
  450. if( $rows_per_page )
  451. {
  452. $pagination = Pagination::factory( array(
  453. 'total_items' => $count,
  454. 'items_per_page' => $rows_per_page,
  455. ) );
  456. $query
  457. ->cached(180)
  458. ->limit( $pagination->items_per_page )
  459. ->offset( $pagination->offset )
  460. ;
  461. $page_links_str = $pagination->render( 'pagination/digg' );
  462. }
  463. $result = $query->execute();
  464. if( $result->count() == 0 )
  465. return array( array( ), '', array( ) );
  466. else
  467. {
  468. $resultArr = $result->as_array( 'id' );
  469. $return = array( );
  470. foreach( $resultArr as $key => $val )
  471. {
  472. $query = Db::select( 'p.price_categories_id', 'p.currencies_id', 'p.price' )
  473. ->from( array( 'shop_prices', 'p' ) )
  474. ->where( 'p.good_id', '=', $key )
  475. ->order_by( 'p.currencies_id' )
  476. ->cached( 30 )
  477. ;
  478. if( is_numeric( $price_categoty ) )
  479. $query->where( 'p.price_categories_id', '=', (int) $price_categoty );
  480. $prices = array( );
  481. $rows = $query->execute()->as_array();
  482. if( $val['quantity'] == 0 )
  483. $val['store_approximate_date'] = Model_Frontend_Goods::getApproximateDate( $val['store_approximate_date'] );
  484. $val['prices'] = $curr->getPrice( $rows );
  485. $val['seo_url'] = $val['seo_url'] ? str_replace( self::$url_search, self::$url_replace, urlencode( $val['seo_url'] ) ) : str_replace( self::$url_search, self::$url_replace, Controller_Admin::to_url( $val['name'] ));
  486. $val['seo_url'] = str_replace( '__', '_', $val['seo_url'] );
  487. $val['seo_url'] = str_replace( '__', '_', $val['seo_url'] );
  488. $val['category_url'] = $val['category_url'] ? str_replace( self::$url_search, self::$url_replace, urlencode( $val['category_url'] ) ) : str_replace( self::$url_search, self::$url_replace, Controller_Admin::to_url( $val['category_name'] ));
  489. $val['category_url'] = str_replace( '__', '_', $val['category_url'] );
  490. $val['category_url'] = str_replace( '__', '_', $val['category_url'] );
  491. $return[$key] = $val;
  492. }
  493. $retPag = $rows_per_page ? $pagination->total_pages : 1;
  494. return array( $return, $page_links_str, $retPag );
  495. }
  496. }
  497. }
  498. static public function search( $rows_per_page = 10, $srchWhat, $sortby = null, $sortasc = 'asc', $brandId = null, $filter = array( ), $lang_id = 1 )
  499. {
  500. $curr = new Model_Frontend_Currencies();
  501. $price_categories_id = 1;
  502. $ids = array( );
  503. $rows = Model_Frontend_Categories::child_categories();
  504. // $childs = Model_Frontend_Categories::find_inner_categories($rows);
  505. $query_c = DB::select( DB::expr( 'COUNT(*) AS mycount' ) )
  506. ->from( array( 'shop_goods', 'g' ) )
  507. ->join( array( 'shop_categories', 'c' ) )
  508. ->on( 'g.categories_id', '=', 'c.id' )
  509. ->join( array( DB::expr( '(select price,good_id from `shop_prices` where currencies_id = ' . $curr->getDefaultCurrency() . ' and price_categories_id = ' . $price_categories_id . ' group by good_id)' ), 'p' ), 'left outer' )
  510. ->on( 'p.good_id', '=', 'g.id' )
  511. ->where( 'p.price', '>', '0' )
  512. ->and_where( 'c.languages_id', '=', $lang_id )
  513. ->and_where_open()
  514. ->or_where( 'g.name', 'like', "%" . $srchWhat . "%" )
  515. ->or_where( 'g.alter_name', 'like', "%" . $srchWhat . "%" )
  516. ->or_where( 'g.short_description', 'like', "%" . $srchWhat . "%" )
  517. ->and_where_close()
  518. ;
  519. $query_c->and_where_open();
  520. foreach( Kohana::config('shop.frontendStatuses') as $key => $item )
  521. {
  522. $query_c->or_where( "g.status", '=', $item );
  523. }
  524. $query_c->and_where_close();
  525. $query = Db::select( 'g.*', array( 'c.name', 'category_name' ), array( 'c.seo_url', 'category_url' ), array( 'p.price', 'price' ), array(DB::expr('IF(g.quantity > 0, 1, 0)'), 'exist') )
  526. ->from( array( 'shop_goods', 'g' ) )
  527. ->join( array( 'shop_categories', 'c' ) )
  528. ->on( 'g.categories_id', '=', 'c.id' )
  529. ->join( array( DB::expr( '(select price,good_id from `shop_prices` where currencies_id = ' . $curr->getDefaultCurrency() . ' and price_categories_id = ' . $price_categories_id . ' group by good_id)' ), 'p' ), 'left outer' )
  530. ->on( 'p.good_id', '=', 'g.id' )
  531. ->where( 'p.price', '>', '0' )
  532. ->and_where( 'c.languages_id', '=', $lang_id )
  533. ->and_where_open()
  534. ->or_where( 'g.name', 'like', "%" . $srchWhat . "%" )
  535. ->or_where( 'g.alter_name', 'like', "%" . $srchWhat . "%" )
  536. ->or_where( 'g.short_description', 'like', "%" . $srchWhat . "%" )
  537. ->and_where_close()
  538. ->order_by( 'exist', 'desc' )
  539. ->order_by( 'p.price', 'desc' )
  540. ;
  541. $query->and_where_open();
  542. foreach( Kohana::config('shop.frontendStatuses') as $key => $item )
  543. {
  544. $query->or_where( "g.status", '=', $item );
  545. }
  546. $query->and_where_close();
  547. if( $brandId !== null )
  548. {
  549. $query_c->and_where( 'brand_id', '=', $brandId );
  550. $query->and_where( 'brand_id', '=', $brandId );
  551. }
  552. $ids = self::getFoundGoods( $srchWhat );
  553. if( !empty( $ids ) )
  554. {
  555. $query_c->or_where( 'g.id', 'in', DB::expr( "(" . implode( ",", $ids ) . ")" ) );
  556. $query->or_where( 'g.id', 'in', DB::expr( "(" . implode( ",", $ids ) . ")" ) );
  557. }
  558. if( isset( $filter['add_fields'] ) )
  559. {
  560. $ids = self::getFilteredGoods( $filter['add_fields'] );
  561. if( empty( $ids ) )
  562. $ids = array( 0 );
  563. $query_c->and_where( 'g.id', 'in', DB::expr( "(" . implode( ",", $ids ) . ")" ) );
  564. $query->and_where( 'g.id', 'in', DB::expr( "(" . implode( ",", $ids ) . ")" ) );
  565. }
  566. // Не помню за что отвечает этот код
  567. // if( !self::validAsc( $sortasc ) )
  568. // $sortasc = 'asc';
  569. // if( $sortby !== null && self::validSortableFields( $sortby ) )
  570. // $query->order_by( $sortby, $sortasc );
  571. // else
  572. // $query->order_by( 'g.name', $sortasc );
  573. $count = $query_c
  574. ->cached( 20 )
  575. ->execute()
  576. ->get( 'mycount' );
  577. if( isset( $_POST['page'] ) )
  578. $_GET['page'] = $_POST['page'];
  579. $pagination = Pagination::factory( array(
  580. 'total_items' => $count,
  581. 'items_per_page' => $rows_per_page,
  582. ) );
  583. $result = $query->cached( 30 )
  584. ->limit( $pagination->items_per_page )
  585. ->offset( $pagination->offset )
  586. ->execute();
  587. $page_links_str = $pagination->render( 'pagination/digg' );
  588. if( $result->count() == 0 )
  589. return array( array( ), '', array( ) );
  590. else
  591. {
  592. $resultArr = $result->as_array( 'id' );
  593. $return = array( );
  594. foreach( $resultArr as $key => $val )
  595. {
  596. $query = Db::select( 'p.price_categories_id', 'p.currencies_id', 'p.price' )
  597. ->from( array( 'shop_prices', 'p' ) )
  598. ->where( 'p.good_id', '=', $key )
  599. ->order_by( 'p.currencies_id' )
  600. ->cached( 30 )
  601. ;
  602. if( is_numeric( $price_categoty ) )
  603. $query->where( 'p.price_categories_id', '=', (int) $price_categoty );
  604. if( $val['quantity'] == 0 )
  605. $val['store_approximate_date'] = Model_Frontend_Goods::getApproximateDate( $val['store_approximate_date'] );
  606. $prices = array( );
  607. $rows = $query->execute()->as_array();
  608. $val['prices'] = $curr->getPrice( $rows );
  609. $val['seo_url'] = $val['seo_url'] ? str_replace( self::$url_search, self::$url_replace, urlencode( $val['seo_url'] ) ) : str_replace( self::$url_search, self::$url_replace, Controller_Admin::to_url( $val['name'] ));
  610. $val['seo_url'] = str_replace( '__', '_', $val['seo_url'] );
  611. $val['seo_url'] = str_replace( '__', '_', $val['seo_url'] );
  612. $val['category_url'] = $val['category_url'] ? str_replace( self::$url_search, self::$url_replace, urlencode( $val['category_url'] ) ) : str_replace( self::$url_search, self::$url_replace, Controller_Admin::to_url( $val['category_name'] ));
  613. $val['category_url'] = str_replace( '__', '_', $val['category_url'] );
  614. $val['category_url'] = str_replace( '__', '_', $val['category_url'] );
  615. $return[$key] = $val;
  616. }
  617. return array( $return, $page_links_str, $pagination->total_pages );
  618. }
  619. }
  620. static public function validSortableFields( $field )
  621. {
  622. $possFields = array( 'name', 'price', 'rating' );
  623. if( in_array( $field, $possFields ) )
  624. return true;
  625. return false;
  626. }
  627. static public function validAsc( $asc )
  628. {
  629. $possValues = array( 'asc', 'desc' );
  630. if( in_array( $asc, $possValues ) )
  631. return true;
  632. return false;
  633. }
  634. static public function getFilterableFields( $categoryId = 0 )
  635. {
  636. if( self::$_filtableFields !== null && $categoryId === self::$_categoryId )
  637. return self::$_filtableFields;
  638. self::$_categoryId = $categoryId;
  639. $res = DB::select( 'p.*' )
  640. ->from( array( 'shop_goods_properties', 'p' ) )
  641. ->join( array( 'shop_categories', 'c' ) )
  642. ->on( 'p.category_id', '=', 'c.id' )
  643. ->where( 'c.languages_id', '=', CURRENT_LANG_ID )
  644. ->where( 'is_filterable', '=', 1 );
  645. if( $categoryId )
  646. $res->where( 'category_id', '=', $categoryId );
  647. $filtableFields = $res->cached( '60' )
  648. ->execute()
  649. ->as_array( 'alias' );
  650. ;
  651. foreach( $filtableFields as &$field )
  652. {
  653. if( $field['type'] == 'select' )
  654. {
  655. $field['defaults'] = explode( '|', $field['defaults'] );
  656. }
  657. }
  658. self::$_filtableFields = $filtableFields;
  659. return $filtableFields;
  660. }
  661. static public function getFilteredGoods( $properties )
  662. {
  663. $sql = "SELECT vse.* " .
  664. "FROM (SELECT shop_goods_properties_values.*, UPPER(GROUP_CONCAT(value_text ,'|' )) AS grc
  665. FROM shop_goods_properties_values
  666. GROUP BY good_id) as vse WHERE ";
  667. foreach( $properties as $propId => $propData )
  668. {
  669. $propId = intval( $propId );
  670. // $sql .= " (";
  671. // $sql .= "properties_category_id = $propId AND ";
  672. $sql .= str_replace( 'value_text', 'vse.grc', self::getMySQLCond( $propData ) ) . " AND";
  673. }
  674. $sql = rtrim( $sql, ' AND' );
  675. //Kohana_log::instance()->add('d', Kohana::debug( $sql ));
  676. $res = DB::query( Database::SELECT, $sql )->cached( 10 )->execute()->as_array();
  677. $resultArray = array( );
  678. if( !$res )
  679. return array( -1 );
  680. foreach( $res as $param )
  681. {
  682. $resultArray[$param['good_id']][] = $param['properties_category_id'];
  683. }
  684. $goodIds = array( );
  685. foreach( $resultArray as $goodId => $goodPropertyIds )
  686. {
  687. if( array_search( 0, array_keys( $properties ) ) !== 0 )
  688. {
  689. $temp = array_diff( array_keys( $properties ), $goodPropertyIds );
  690. if( empty( $temp ) )
  691. {
  692. $goodIds[] = $goodId;
  693. }
  694. }else
  695. {
  696. $goodIds[] = $goodId;
  697. }
  698. }
  699. return $goodIds;
  700. }
  701. static public function getFilteredGoodsForCategory( $properties )
  702. {
  703. $sql = "SELECT * FROM shop_goods_properties_values WHERE CASE ";
  704. foreach( $properties as $propId => $propData )
  705. {
  706. $propId = intval( $propId );
  707. $sql .= "when properties_category_id = " . (int) $propId . " then " . self::getMySQLCond( $propData );
  708. }
  709. $sql .= " end";
  710. $res = DB::query( Database::SELECT, $sql )->cached( 10 )->execute()->as_array();
  711. $resultArray = array( );
  712. if( !$res )
  713. return array( -1 );
  714. foreach( $res as $param )
  715. {
  716. $resultArray[$param['good_id']][] = $param['properties_category_id'];
  717. }
  718. $goodIds = array( );
  719. foreach( $resultArray as $goodId => $goodPropertyIds )
  720. {
  721. // if( array_search(0, array_keys($properties) ) !== 0 )
  722. // {
  723. $temp = array_diff( array_keys( $properties ), $goodPropertyIds );
  724. if( empty( $temp ) )
  725. {
  726. $goodIds[] = $goodId;
  727. }
  728. // }else{
  729. // $goodIds[] = $goodId;
  730. // }
  731. }
  732. return $goodIds;
  733. }
  734. static public function getFoundGoods( $srchWhat )
  735. {
  736. $sql = "select * from shop_goods_properties_values where " .
  737. "value_text like " . Database::instance()->escape( "%" . $srchWhat . "%" ) .
  738. " or value_varchar like " . Database::instance()->escape( "%" . $srchWhat . "%" )
  739. . "";
  740. $res = DB::query( Database::SELECT, $sql )->cached( 10 )->execute()->as_array( 'good_id' );
  741. return array_keys( $res );
  742. }
  743. static public function getMySQLCond( $data, $search = false )
  744. {
  745. $possTypes = array( 'int', 'float', 'date', 'text', 'varchar' );
  746. if( $data['type'] == 'select' )
  747. $data['type'] = 'text';
  748. if( !in_array( $data['type'], $possTypes ) )
  749. throw new Exception( 'Incorrect data' );
  750. if( $search )
  751. $cond = array( "", "" );
  752. else
  753. $cond = array( 'from' => ">", 'to' => "<" );
  754. if( is_array( $data['data'] ) )
  755. {
  756. $where = array( );
  757. foreach( $data['data'] as $key => $p )
  758. {
  759. $where[] = " value_{$data['type']} {$cond[$key]}= " . Database::instance()->escape( $data['data'][0] ) . "";
  760. }
  761. return implode( " and ", $where );
  762. }else
  763. if( $data['type'] == 'text' || $data['type'] == 'varchar' )
  764. return " value_{$data['type']} like UPPER(" . Database::instance()->escape( "%" . $data['data'] . '%' ) . ") ";
  765. else
  766. return " value_{$data['type']} = " . Database::instance()->escape( $data['data'] ) . " ";
  767. }
  768. function getLastNewGoods()
  769. {
  770. $catids = Kohana::config('shop.topCatsToNew');
  771. }
  772. }