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

https://bitbucket.org/seyar/kinda.local · PHP · 978 lines · 975 code · 3 blank · 0 comment · 0 complexity · 3d019b849132b38048dece09174806f0 MD5 · raw file

  1. <?php
  2. defined( 'SYSPATH' ) OR die( 'No direct access allowed.' );
  3. class Model_Frontend_Categories extends Model_Admin
  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','parent_id', 'name','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( $sortby !== null && self::validSortableFields( $sortby ) )
  441. $query->order_by( $sortby, $sortasc );
  442. else
  443. $query->order_by( 'p.price', 'desc' );
  444. $count = $query_c
  445. ->execute()
  446. ->get( 'mycount' );
  447. if( isset( $_POST['page'] ) )
  448. $_GET['page'] = $_POST['page'];
  449. if( $rows_per_page )
  450. {
  451. $pagination = Pagination::factory(array(
  452. 'previous_page' => '<img src="/templates/kinda/images/pagination_prev.png" alt="" class="vMiddle"/>',
  453. 'next_page' => '<img src="/templates/kinda/images/pagination_next.png" alt="" class="vMiddle"/>',
  454. 'total_items' => $count,
  455. 'items_per_page' => $rows_per_page,
  456. ));
  457. $query
  458. ->cached(180)
  459. ->limit( $pagination->items_per_page )
  460. ->offset( $pagination->offset )
  461. ;
  462. $page_links_str = $pagination->render( 'pagination/digg' );
  463. }
  464. $result = $query->execute();
  465. if( $result->count() == 0 )
  466. return array( array( ), '', array( ) );
  467. else
  468. {
  469. $resultArr = $result->as_array( 'id' );
  470. $return = array( );
  471. foreach( $resultArr as $key => $val )
  472. {
  473. $query = Db::select( 'p.price_categories_id', 'p.currencies_id', 'p.price', 'p.oldprice' )
  474. ->from( array( 'shop_prices', 'p' ) )
  475. ->where( 'p.good_id', '=', $key )
  476. ->order_by( 'p.currencies_id' )
  477. ->cached( 30 )
  478. ;
  479. if( is_numeric( $price_categoty ) )
  480. $query->where( 'p.price_categories_id', '=', (int) $price_categoty );
  481. $prices = array( );
  482. $rows = $query->execute()->as_array();
  483. if( $val['quantity'] == 0 )
  484. $val['store_approximate_date'] = Model_Frontend_Goods::getApproximateDate( $val['store_approximate_date'] );
  485. $val['prices'] = $curr->getPrice( $rows );
  486. $val['oldprices'] = $curr->getPrice( $rows, 'oldprice' );
  487. $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'] ));
  488. $val['seo_url'] = str_replace( '__', '_', $val['seo_url'] );
  489. $val['seo_url'] = str_replace( '__', '_', $val['seo_url'] );
  490. $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'] ));
  491. $val['category_url'] = str_replace( '__', '_', $val['category_url'] );
  492. $val['category_url'] = str_replace( '__', '_', $val['category_url'] );
  493. $return[$key] = $val;
  494. }
  495. $retPag = $rows_per_page ? $pagination->total_pages : 1;
  496. return array( $return, $page_links_str, $retPag );
  497. }
  498. }
  499. }
  500. static public function search( $rows_per_page = 10, $srchWhat, $sortby = null, $sortasc = 'asc', $brandId = null, $filter = array( ), $lang_id = 1 )
  501. {
  502. $curr = new Model_Frontend_Currencies();
  503. $price_categories_id = 1;
  504. $ids = array( );
  505. $rows = Model_Frontend_Categories::child_categories();
  506. // $childs = Model_Frontend_Categories::find_inner_categories($rows);
  507. $query_c = DB::select( DB::expr( 'COUNT(*) AS mycount' ) )
  508. ->from( array( 'shop_goods', 'g' ) )
  509. ->join( array( 'shop_categories', 'c' ) )
  510. ->on( 'g.categories_id', '=', 'c.id' )
  511. ->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' )
  512. ->on( 'p.good_id', '=', 'g.id' )
  513. ->where( 'p.price', '>', '0' )
  514. ->and_where( 'c.languages_id', '=', $lang_id )
  515. ->and_where_open()
  516. ->or_where( 'g.name', 'like', "%" . $srchWhat . "%" )
  517. ->or_where( 'g.scu', 'like', "%" . $srchWhat . "%" )
  518. ->or_where( 'g.alter_name', 'like', "%" . $srchWhat . "%" )
  519. ->or_where( 'g.short_description', 'like', "%" . $srchWhat . "%" )
  520. ->and_where_close()
  521. ;
  522. $query_c->and_where_open();
  523. foreach( Kohana::config('shop.frontendStatuses') as $key => $item )
  524. {
  525. $query_c->or_where( "g.status", '=', $item );
  526. }
  527. $query_c->and_where_close();
  528. $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') )
  529. ->from( array( 'shop_goods', 'g' ) )
  530. ->join( array( 'shop_categories', 'c' ) )
  531. ->on( 'g.categories_id', '=', 'c.id' )
  532. ->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' )
  533. ->on( 'p.good_id', '=', 'g.id' )
  534. ->where( 'p.price', '>', '0' )
  535. ->and_where( 'c.languages_id', '=', $lang_id )
  536. ->and_where_open()
  537. ->or_where( DB::expr('LOWER(g.name)'), 'like', "%" . strtolower($srchWhat) . "%" )
  538. ->or_where( DB::expr('LOWER(g.scu)'), 'like', "%" . strtolower($srchWhat) . "%" )
  539. ->or_where( DB::expr('LOWER(g.alter_name)'), 'like', "%" . strtolower($srchWhat) . "%" )
  540. ->or_where( DB::expr('LOWER(g.short_description)'), 'like', "%" . strtolower($srchWhat) . "%" )
  541. ->and_where_close()
  542. ->order_by( 'exist', 'desc' )
  543. ->order_by( 'p.price', 'desc' )
  544. ;
  545. $query->and_where_open();
  546. foreach( Kohana::config('shop.frontendStatuses') as $key => $item )
  547. {
  548. $query->or_where( "g.status", '=', $item );
  549. }
  550. $query->and_where_close();
  551. if( $brandId !== null )
  552. {
  553. $query_c->and_where( 'brand_id', '=', $brandId );
  554. $query->and_where( 'brand_id', '=', $brandId );
  555. }
  556. $ids = self::getFoundGoods( $srchWhat );
  557. if( !empty( $ids ) )
  558. {
  559. $query_c->or_where( 'g.id', 'in', DB::expr( "(" . implode( ",", $ids ) . ")" ) );
  560. $query->or_where( 'g.id', 'in', DB::expr( "(" . implode( ",", $ids ) . ")" ) );
  561. }
  562. if( isset( $filter['add_fields'] ) )
  563. {
  564. $ids = self::getFilteredGoods( $filter['add_fields'] );
  565. if( empty( $ids ) )
  566. $ids = array( 0 );
  567. $query_c->and_where( 'g.id', 'in', DB::expr( "(" . implode( ",", $ids ) . ")" ) );
  568. $query->and_where( 'g.id', 'in', DB::expr( "(" . implode( ",", $ids ) . ")" ) );
  569. }
  570. // Не помню за что отвечает этот код
  571. // if( !self::validAsc( $sortasc ) )
  572. // $sortasc = 'asc';
  573. // if( $sortby !== null && self::validSortableFields( $sortby ) )
  574. // $query->order_by( $sortby, $sortasc );
  575. // else
  576. // $query->order_by( 'g.name', $sortasc );
  577. $count = $query_c
  578. ->cached( 20 )
  579. ->execute()
  580. ->get( 'mycount' );
  581. if( isset( $_POST['page'] ) )
  582. $_GET['page'] = $_POST['page'];
  583. $pagination = Pagination::factory( array(
  584. 'total_items' => $count,
  585. 'items_per_page' => $rows_per_page,
  586. ) );
  587. //die(Kohana::debug($query->__toString()));
  588. $result = $query->cached( 30 )
  589. ->limit( $pagination->items_per_page )
  590. ->offset( $pagination->offset )
  591. ->execute();
  592. $page_links_str = $pagination->render( 'pagination/digg' );
  593. if( $result->count() == 0 )
  594. return array( array( ), '', array( ) );
  595. else
  596. {
  597. $resultArr = $result->as_array( 'id' );
  598. $return = array( );
  599. foreach( $resultArr as $key => $val )
  600. {
  601. $query = Db::select( 'p.price_categories_id', 'p.currencies_id', 'p.price' )
  602. ->from( array( 'shop_prices', 'p' ) )
  603. ->where( 'p.good_id', '=', $key )
  604. ->order_by( 'p.currencies_id' )
  605. ->cached( 30 )
  606. ;
  607. if( is_numeric( $price_categoty ) )
  608. $query->where( 'p.price_categories_id', '=', (int) $price_categoty );
  609. if( $val['quantity'] == 0 )
  610. $val['store_approximate_date'] = Model_Frontend_Goods::getApproximateDate( $val['store_approximate_date'] );
  611. $prices = array( );
  612. $rows = $query->execute()->as_array();
  613. $val['prices'] = $curr->getPrice( $rows );
  614. $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'] ));
  615. $val['seo_url'] = str_replace( '__', '_', $val['seo_url'] );
  616. $val['seo_url'] = str_replace( '__', '_', $val['seo_url'] );
  617. $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'] ));
  618. $val['category_url'] = str_replace( '__', '_', $val['category_url'] );
  619. $val['category_url'] = str_replace( '__', '_', $val['category_url'] );
  620. $return[$key] = $val;
  621. }
  622. return array( $return, $page_links_str, $pagination->total_pages );
  623. }
  624. }
  625. static public function validSortableFields( $field )
  626. {
  627. $possFields = array( 'name', 'price', 'scu' );
  628. if( in_array( $field, $possFields ) )
  629. return true;
  630. return false;
  631. }
  632. static public function validAsc( $asc )
  633. {
  634. $possValues = array( 'asc', 'desc' );
  635. if( in_array( $asc, $possValues ) )
  636. return true;
  637. return false;
  638. }
  639. static public function getFilterableFields( $categoryId = 0 )
  640. {
  641. if( self::$_filtableFields !== null && $categoryId === self::$_categoryId )
  642. return self::$_filtableFields;
  643. self::$_categoryId = $categoryId;
  644. $res = DB::select( 'p.*' )
  645. ->from( array( 'shop_goods_properties', 'p' ) )
  646. ->join( array( 'shop_categories', 'c' ) )
  647. ->on( 'p.category_id', '=', 'c.id' )
  648. ->where( 'c.languages_id', '=', CURRENT_LANG_ID )
  649. ->where( 'is_filterable', '=', 1 );
  650. if( $categoryId )
  651. $res->where( 'category_id', '=', $categoryId );
  652. $filtableFields = $res->cached( '60' )
  653. ->execute()
  654. ->as_array( 'alias' );
  655. ;
  656. foreach( $filtableFields as &$field )
  657. {
  658. if( $field['type'] == 'select' )
  659. {
  660. $field['defaults'] = explode( '|', $field['defaults'] );
  661. }
  662. }
  663. self::$_filtableFields = $filtableFields;
  664. return $filtableFields;
  665. }
  666. static public function getFilteredGoods( $properties )
  667. {
  668. $sql = "SELECT vse.* " .
  669. "FROM (SELECT shop_goods_properties_values.*, UPPER(GROUP_CONCAT(value_text ,'|' )) AS grc
  670. FROM shop_goods_properties_values
  671. GROUP BY good_id) as vse WHERE ";
  672. foreach( $properties as $propId => $propData )
  673. {
  674. $propId = intval( $propId );
  675. // $sql .= " (";
  676. // $sql .= "properties_category_id = $propId AND ";
  677. $sql .= str_replace( 'value_text', 'vse.grc', self::getMySQLCond( $propData ) ) . " AND";
  678. }
  679. $sql = rtrim( $sql, ' AND' );
  680. //Kohana_log::instance()->add('d', Kohana::debug( $sql ));
  681. $res = DB::query( Database::SELECT, $sql )->cached( 10 )->execute()->as_array();
  682. $resultArray = array( );
  683. if( !$res )
  684. return array( -1 );
  685. foreach( $res as $param )
  686. {
  687. $resultArray[$param['good_id']][] = $param['properties_category_id'];
  688. }
  689. $goodIds = array( );
  690. foreach( $resultArray as $goodId => $goodPropertyIds )
  691. {
  692. if( array_search( 0, array_keys( $properties ) ) !== 0 )
  693. {
  694. $temp = array_diff( array_keys( $properties ), $goodPropertyIds );
  695. if( empty( $temp ) )
  696. {
  697. $goodIds[] = $goodId;
  698. }
  699. }else
  700. {
  701. $goodIds[] = $goodId;
  702. }
  703. }
  704. return $goodIds;
  705. }
  706. static public function getFilteredGoodsForCategory( $properties )
  707. {
  708. $sql = "SELECT * FROM shop_goods_properties_values WHERE CASE ";
  709. foreach( $properties as $propId => $propData )
  710. {
  711. $propId = intval( $propId );
  712. $sql .= "when properties_category_id = " . (int) $propId . " then " . self::getMySQLCond( $propData );
  713. }
  714. $sql .= " end";
  715. $res = DB::query( Database::SELECT, $sql )->cached( 10 )->execute()->as_array();
  716. $resultArray = array( );
  717. if( !$res )
  718. return array( -1 );
  719. foreach( $res as $param )
  720. {
  721. $resultArray[$param['good_id']][] = $param['properties_category_id'];
  722. }
  723. $goodIds = array( );
  724. foreach( $resultArray as $goodId => $goodPropertyIds )
  725. {
  726. // if( array_search(0, array_keys($properties) ) !== 0 )
  727. // {
  728. $temp = array_diff( array_keys( $properties ), $goodPropertyIds );
  729. if( empty( $temp ) )
  730. {
  731. $goodIds[] = $goodId;
  732. }
  733. // }else{
  734. // $goodIds[] = $goodId;
  735. // }
  736. }
  737. return $goodIds;
  738. }
  739. static public function getFoundGoods( $srchWhat )
  740. {
  741. $sql = "select * from shop_goods_properties_values where " .
  742. "value_text like " . Database::instance()->escape( "%" . $srchWhat . "%" ) .
  743. " or value_varchar like " . Database::instance()->escape( "%" . $srchWhat . "%" )
  744. . "";
  745. $res = DB::query( Database::SELECT, $sql )->cached( 10 )->execute()->as_array( 'good_id' );
  746. return array_keys( $res );
  747. }
  748. static public function getMySQLCond( $data, $search = false )
  749. {
  750. $possTypes = array( 'int', 'float', 'date', 'text', 'varchar' );
  751. if( $data['type'] == 'select' )
  752. $data['type'] = 'text';
  753. if( !in_array( $data['type'], $possTypes ) )
  754. throw new Exception( 'Incorrect data' );
  755. if( $search )
  756. $cond = array( "", "" );
  757. else
  758. $cond = array( 'from' => ">", 'to' => "<" );
  759. if( is_array( $data['data'] ) )
  760. {
  761. $where = array( );
  762. foreach( $data['data'] as $key => $p )
  763. {
  764. $where[] = " value_{$data['type']} {$cond[$key]}= " . Database::instance()->escape( $data['data'][0] ) . "";
  765. }
  766. return implode( " and ", $where );
  767. }else
  768. if( $data['type'] == 'text' || $data['type'] == 'varchar' )
  769. return " value_{$data['type']} like UPPER(" . Database::instance()->escape( "%" . $data['data'] . '%' ) . ") ";
  770. else
  771. return " value_{$data['type']} = " . Database::instance()->escape( $data['data'] ) . " ";
  772. }
  773. function getLastNewGoods()
  774. {
  775. $catids = Kohana::config('shop.topCatsToNew');
  776. }
  777. public function getFirstSecondDepth()
  778. {
  779. $this->_table = 'shop_categories';
  780. $first = array();
  781. $first = parent::getItems(array("id",'parent_id',"name","seo_url","display_mode"),
  782. array(array('parent_id','=',Kohana::config('shop.root_category_id'))), 60,TRUE,'id',NULL, array('order_id','asc') );
  783. $second = parent::getItems(array("id",'parent_id',"name","seo_url","display_mode"),
  784. array(array('parent_id','IN',array_keys($first))), 60,TRUE,'id');
  785. $return = array();
  786. foreach( $second as $item )
  787. {
  788. $first[$item['parent_id']]['children'][] = $item;
  789. }
  790. return $first;
  791. }
  792. static function getFirst( $lang_id = 1 )
  793. {
  794. $q = DB::select('id','seo_url')
  795. ->from('shop_categories')
  796. ->where('status','=','verified')
  797. ->and_where('parent_id','=',1)
  798. ->and_where('languages_id','=',$lang_id)
  799. ->limit(1)
  800. ->execute()
  801. ;
  802. if( $q->count() == 0 ) return array();
  803. return $q->current();
  804. }
  805. }