PageRenderTime 252ms CodeModel.GetById 62ms app.highlight 113ms RepoModel.GetById 29ms app.codeStats 1ms

/lib/packages/products/product.class.php

https://bitbucket.org/navigatecms/navigatecms
PHP | 835 lines | 662 code | 134 blank | 39 comment | 74 complexity | 9cd69e1326df9a762d86166420e0f790 MD5 | raw file
  1<?php
  2require_once(NAVIGATE_PATH.'/lib/packages/templates/template.class.php');
  3require_once(NAVIGATE_PATH.'/lib/packages/brands/brand.class.php');
  4require_once(NAVIGATE_PATH.'/lib/packages/webdictionary/webdictionary.class.php');
  5require_once(NAVIGATE_PATH.'/lib/packages/webdictionary/webdictionary_history.class.php');
  6require_once(NAVIGATE_PATH.'/lib/packages/paths/path.class.php');
  7require_once(NAVIGATE_PATH.'/lib/packages/webuser_votes/webuser_vote.class.php');
  8
  9class product
 10{
 11	public $id;
 12	public $website;
 13	public $category;
 14	public $template;
 15    public $date_to_display;
 16	public $date_published;
 17	public $date_unpublish;
 18	public $galleries;
 19	public $date_created;
 20	public $date_modified;
 21	public $comments_enabled_to; // 0 => nobody, 1=>registered, 2=>everyone
 22	public $comments_moderator; // user_id
 23	public $access; // 0 => everyone, 1 => logged in, 2 => not logged in, 3 => selected webuser groups
 24    public $groups;
 25	public $permission; // 0 => public, 1 => private (only navigate cms users), 2 => hidden
 26	public $views;
 27	public $author;
 28	public $votes;
 29	public $score;
 30	public $position;
 31
 32	public $brand;
 33
 34    public $sku; // stock-keeping unit (must be unique!)
 35    public $barcode;
 36    public $type;   // defaults: 1 => shippable (standard), 2 => downloadable
 37
 38    public $width;
 39    public $height;
 40    public $depth;
 41    public $size_unit;
 42
 43    public $weight;
 44    public $weight_unit;
 45
 46    public $inventory;
 47    public $stock_available;   // including all variants
 48
 49    public $cost;
 50    public $cost_currency;
 51    public $base_price;
 52    public $base_price_currency;
 53    public $tax_class;
 54    public $tax_value;
 55
 56    public $sale_begin_date;
 57    public $sale_end_date;
 58    public $sale_price;
 59    public $sale_price_currency;
 60
 61    // reserved for future use
 62    /*
 63        public $allow_preorder; // can be purchased even when no stock is available
 64        public $hide_if_no_stock;   // hide the product when no stock available
 65        public $low_stock_threshold; // when the product has that number of units, it is considered "low stock"
 66        public $product_available_date;
 67    	public $variants;
 68    */
 69
 70    public $options;
 71
 72    public $dictionary;
 73    public $paths;
 74	public $properties;
 75
 76    private $_comments_count;
 77		
 78	public function load($id)
 79	{
 80		global $DB;
 81		global $website;
 82		
 83		if($DB->query('SELECT * FROM nv_products 
 84						WHERE id = '.intval($id).'
 85						  AND website = '.$website->id))
 86		{
 87			$data = $DB->result();
 88			$this->load_from_resultset($data); // there will be as many entries as languages enabled
 89		}
 90	}
 91	
 92	public function load_from_resultset($rs)
 93	{
 94		$main = $rs[0];
 95
 96		$this->id				= $main->id;
 97		$this->website   		= $main->website;
 98		$this->category			= $main->category;
 99		$this->template			= $main->template;
100		$this->date_to_display	= (empty($main->date_to_display)? '' : $main->date_to_display);
101		$this->date_published	= (empty($main->date_published)? '' : $main->date_published);
102		$this->date_unpublish	= (empty($main->date_unpublish)? '' : $main->date_unpublish);
103		$this->date_created		= $main->date_created;
104		$this->date_modified	= $main->date_modified;		
105		$this->galleries		= mb_unserialize($main->galleries);
106		$this->comments_enabled_to = $main->comments_enabled_to;
107		$this->comments_moderator = $main->comments_moderator;
108		$this->access			= $main->access;	
109		$this->permission		= $main->permission;		
110		$this->author			= $main->author;
111		$this->views			= $main->views;
112		$this->votes			= $main->votes;
113		$this->score			= $main->score;
114		$this->position			= $main->position;
115
116		$this->dictionary		= webdictionary::load_element_strings('product', $this->id);
117		$this->paths			= path::loadElementPaths('product', $this->id);
118
119        // to get the array of groups first we remove the "g" character
120        $this->groups           = $main->groups;
121        if(!is_array($this->groups))
122        {
123            // to get the array of groups first we remove the "g" character
124            $groups = str_replace('g', '', $this->groups);
125            $this->groups = explode(',', $groups);
126        }
127
128        if(!is_array($this->groups))
129            $this->groups = array($this->groups);
130
131        $this->brand            =  $main->brand;
132
133        $this->sku              =  $main->sku;  // must be unique!
134        $this->barcode          =  $main->barcode;
135
136        $this->width            =  $main->width;
137        $this->height           =  $main->height;
138        $this->depth            =  $main->depth;
139        $this->size_unit        =  $main->size_unit;
140
141        $this->weight           =  $main->weight;
142        $this->weight_unit      =  $main->weight_unit;
143
144        $this->type             =  $main->type;
145        $this->inventory        =  $main->inventory;
146        $this->stock_available  =  $main->stock_available; // including all variants
147
148        $this->base_price           =  $main->base_price;
149        $this->base_price_currency  =  $main->base_price_currency;
150        $this->tax_class            =  $main->tax_class;
151        $this->tax_value            =  $main->tax_value;
152        $this->cost                 =  $main->cost;
153        $this->cost_currency        =  $main->cost_currency;
154
155        /*
156         * falten per afegir:
157
158        public $sale_begin_date;
159        public $sale_end_date;
160        public $sale_price;
161        public $sale_price_currency;
162
163        public $options;
164         */
165    }
166	
167	public function load_from_post()
168	{
169		global $website;
170		global $user;
171
172		$this->category			= intval($_REQUEST['category']);
173		$this->template			= $_REQUEST['template'];
174		$this->author			= intval($_REQUEST['item-author']);
175		$this->brand			= $_REQUEST['product-brand-id'];
176
177		if((!empty($this->brand) && !is_numeric($this->brand)) || $this->brand === 0)
178        {
179            // new brand! insert new object into database
180            $brand = new brand();
181            $brand->name = trim($_REQUEST['product-brand']);
182            $brand->save();
183            $this->brand = $brand->id;
184        }
185
186		$this->date_to_display	= (empty($_REQUEST['date_to_display'])? '' : core_date2ts($_REQUEST['date_to_display']));
187		$this->date_published	= (empty($_REQUEST['date_published'])? '' : core_date2ts($_REQUEST['date_published']));
188		$this->date_unpublish	= (empty($_REQUEST['date_unpublish'])? '' : core_date2ts($_REQUEST['date_unpublish']));
189		$this->access			= intval($_REQUEST['access']);
190
191        $this->groups	        = $_REQUEST['groups'];
192        if($this->access < 3)
193            $this->groups = array();
194
195		if($user->permission("products.publish") != 'false')
196			$this->permission = intval($_REQUEST['permission']);
197
198        // if comment settings were not visible, keep the original values
199        if(isset($_REQUEST['product-comments_enabled_to']))
200        {
201            $this->comments_enabled_to 	= intval($_REQUEST['product-comments_enabled_to']);
202            $this->comments_moderator 	= intval($_REQUEST['product-comments_moderator']);
203        }
204
205		// language strings and options
206		$this->dictionary = array();
207		$this->paths = array();
208
209		$template = $this->load_template();
210
211		$fields = array('title', 'tags');
212		
213		if(!is_array($template->sections))
214            $template->sections = array('id' => 'main');
215		
216		foreach($template->sections as $section)
217		{			
218			if(is_object($section)) 
219				$section = (array) $section;
220
221			if(is_array($section))
222				$section = $section['id'];
223			
224			$fields[] = 'section-'.$section;	
225		}
226		
227		foreach($_REQUEST as $key => $value)
228		{
229			if(empty($value)) continue;
230			
231			foreach($fields as $field)
232			{				
233				if(substr($key, 0, strlen($field.'-'))==$field.'-')
234					$this->dictionary[substr($key, strlen($field.'-'))][$field] = $value;
235			}
236
237			if(substr($key, 0, strlen('path-'))=='path-')
238                $this->paths[substr($key, strlen('path-'))] = $value;
239		}
240
241		// image galleries
242		$this->galleries = array();
243		
244		$items = explode("#", $_REQUEST['products-gallery-elements-order']);
245		if(!is_array($items)) $items = array();
246		$gallery_items = array();
247		$gallery_items[0] = array();
248		if(!is_array($website->languages)) $website->languages = array();
249		foreach($items as $item)
250		{
251			if(empty($item)) continue;
252			
253			// capture image captions
254			$gallery_items[0][$item] = array();
255			
256			foreach($website->languages_list as $lang)
257			{
258				$gallery_items[0][$item][$lang] = $_REQUEST['products-gallery-item-'.$item.'-dictionary-'.$lang];
259			}
260		}
261		
262		$this->galleries = $gallery_items;
263		// galleries[0] = array( [id-file] => array(es => '', ca => '',.. ), [id-file-2] => array... )
264
265        $this->sku              =  $_REQUEST['product-sku'];
266        $this->barcode          =  $_REQUEST['product-barcode'];
267
268        $this->width            =  core_string2decimal($_REQUEST['product-width']);
269        $this->height           =  core_string2decimal($_REQUEST['product-height']);
270        $this->depth            =  core_string2decimal($_REQUEST['product-depth']);
271        $this->size_unit        =  $_REQUEST['product-size_unit'];
272
273        $this->weight           =  core_string2decimal($_REQUEST['product-weight']);
274        $this->weight_unit      =  $_REQUEST['product-weight_unit'];
275
276        $this->inventory        =  $_REQUEST['product-track_inventory'];
277        $this->stock_available  =  $_REQUEST['product-stock_available'];
278
279        $this->type             =  $_REQUEST['product-type'];
280
281        $this->base_price           =  core_string2decimal($_REQUEST['product-base_price']);
282        $this->base_price_currency  =  $_REQUEST['product-base_price_currency'];
283        $this->tax_class            =  $_REQUEST['product-tax_class'];
284        $this->tax_value            =  core_string2decimal($_REQUEST['product-tax_value']);
285        $this->cost                 =  core_string2decimal($_REQUEST['product-cost']);
286        $this->cost_currency        =  $_REQUEST['product-cost_currency'];
287    }
288	
289	
290	public function save()
291	{
292		if(!empty($this->id))
293			return $this->update();
294		else
295			return $this->insert();			
296	}
297	
298	public function delete()
299	{
300		global $DB;
301		global $user;
302
303		if($user->permission("products.delete") == 'false')
304			throw new Exception(t(610, "Sorry, you are not allowed to execute this function."));
305
306		if(!empty($this->id) && !empty($this->website))
307		{
308		    // TODO: remove variants, price-listings, etc.
309
310			// remove dictionary elements
311			webdictionary::save_element_strings('product', $this->id, array(), $this->website);
312			
313			// remove path elements
314			path::saveElementPaths('product', $this->id, array(), $this->website);
315			
316			// remove all votes assigned to element
317			webuser_vote::remove_object_votes('product', $this->id);
318
319            // remove all element properties
320            property::remove_properties('product', $this->id, $this->website);
321
322            // remove grid notes
323            grid_notes::remove_all('product', $this->id);
324
325            // finally remove the product
326			$DB->execute('
327			    DELETE FROM nv_products
328				 WHERE id = '.intval($this->id).'
329				   AND website = '.$this->website
330            );
331		}
332		
333		return $DB->get_affected_rows();		
334	}
335	
336	public function insert()
337	{
338		global $DB;
339		global $website;
340		global $events;
341		global $user;
342
343		if(!empty($user->id))
344		{
345			if( $user->permission("products.create") == 'false'    ||
346				!structure::category_allowed($this->category)
347			)
348				throw new Exception(t(610, "Sorry, you are not allowed to execute this function."));
349		}
350
351		$this->date_created  = core_time();		
352		$this->date_modified = core_time();
353
354        if(empty($this->comments_enabled_to))
355        {
356            // apply default comment settings from website properties
357            $this->comments_enabled_to = $website->comments_enabled_for;
358            $this->comments_moderator = $website->comments_default_moderator;
359            if($this->comments_moderator == 'c_author')
360                $this->comments_moderator = $this->author;
361        }
362
363        $groups = '';
364        if(is_array($this->groups))
365        {
366            $this->groups = array_unique($this->groups); // remove duplicates
367            $this->groups = array_filter($this->groups); // remove empty
368            if(!empty($this->groups))
369                $groups = 'g'.implode(',g', $this->groups);
370        }
371
372        if($groups == 'g')
373            $groups = '';
374
375		if(empty($this->website))
376			$this->website = $website->id;
377
378		if(!empty($user->id) && $user->permission("products.publish") == 'false')
379		{
380			if($this->permission == 0)
381				$this->permission = 1;
382		}
383
384		if(empty($this->position))
385		{
386			$last_position_in_category = $DB->query_single('MAX(position)', 'nv_products', ' category = '.value_or_default($this->category, 0));
387			$default_position = $last_position_in_category + 1;
388		}
389
390        $ok = $DB->execute('
391            INSERT INTO nv_products
392                (id, website, category, type, template, author, brand,
393                 date_to_display, date_published, date_unpublish, date_created, date_modified,
394                 sku, barcode, base_price, base_price_currency, tax_class, tax_value, cost, cost_currency,
395                 sale_price, sale_price_currency, sale_begin_date, sale_end_date,
396                 width, height, depth, size_unit, weight, weight_unit,
397                 inventory, stock_available, 
398                 options,
399                 galleries, comments_enabled_to, comments_moderator,
400                 access, groups, permission, views, votes, score, position)
401            VALUES
402                (:id, :website, :category, :type, :template, :author, :brand,
403                 :date_to_display, :date_published, :date_unpublish, :date_created, :date_modified,
404                 :sku, :barcode, :base_price, :base_price_currency, :tax_class, :tax_value, :cost, :cost_currency,
405                 :sale_price, :sale_price_currency, :sale_begin_date, :sale_end_date,
406                 :width, :height, :depth, :size_unit, :weight, :weight_unit,
407                 :inventory, :stock_available,
408                 :options,
409                 :galleries, :comments_enabled_to, :comments_moderator,
410                 :access, :groups, :permission, :views, :votes, :score, :position)
411             ',
412            array(
413                ":id" => 0,
414                ":website" => $this->website,
415                ":category" => value_or_default($this->category, 0),
416                ":template" => value_or_default($this->template, ''),
417                ":type" => value_or_default($this->type, 0),
418                ":brand" => value_or_default($this->brand, 0),
419                ":date_to_display" => intval($this->date_to_display),
420                ":date_published" => intval($this->date_published),
421                ":date_unpublish" => intval($this->date_unpublish),
422                ":date_created" => $this->date_created,
423                ":date_modified" => $this->date_modified,
424                ":sku" =>  value_or_default($this->sku, ''),
425                ":barcode" =>  value_or_default($this->barcode, ''),
426                ":base_price" =>  value_or_default($this->base_price, 0),
427                ":base_price_currency" =>  value_or_default($this->base_price_currency, ""),
428                ":tax_class" =>  value_or_default($this->tax_class, "included"),
429                ":tax_value" =>  value_or_default($this->tax_value, 0),
430                ":cost" =>  value_or_default($this->cost, 0),
431                ":cost_currency" =>  value_or_default($this->cost_currency, ""),
432                ":sale_price" => value_or_default($this->sale_price, 0),
433                ":sale_price_currency" =>  value_or_default($this->sale_price_currency, ""),
434                ":sale_begin_date" => intval($this->sale_begin_date),
435                ":sale_end_date" => intval($this->sale_end_date),
436                ":width" => value_or_default($this->width, 0),
437                ":height" => value_or_default($this->height, 0),
438                ":depth" => value_or_default($this->depth, 0),
439                ":size_unit" => value_or_default($this->size_unit, 'cm'),
440                ":weight" => value_or_default($this->weight, 0),
441                ":weight_unit" => value_or_default($this->weight_unit, 'kg'),
442                ":inventory" => value_or_default($this->inventory, 0),
443                ":stock_available" => value_or_default($this->stock_available, 0),
444                ":options" => json_encode($this->options),
445                ":author" => value_or_default($this->author, 0),
446                ":galleries" => serialize($this->galleries),
447                ":comments_enabled_to" => value_or_default($this->comments_enabled_to, 0),
448                ":comments_moderator" => value_or_default($this->comments_moderator, 0),
449                ":access" => value_or_default($this->access, 0),
450                ":groups" => $groups,
451                ":permission" => value_or_default($this->permission, 0),
452                ":views" => 0,
453                ":votes" => 0,
454                ":score" => 0,
455	            ":position" => value_or_default($this->position, $default_position)
456            )
457        );
458			
459		if(!$ok)
460			throw new Exception($DB->get_last_error());
461
462		$this->id = $DB->get_last_id();
463
464		webdictionary::save_element_strings('product', $this->id, $this->dictionary, $this->website);
465		webdictionary_history::save_element_strings('product', $this->id, $this->dictionary, false, $this->website);
466   		path::saveElementPaths('product', $this->id, $this->paths, $this->website);
467
468		if(method_exists($events, 'trigger'))
469		{
470			$events->trigger(
471				'product',
472				'save',
473				array(
474					'product' => $this
475				)
476			);
477		}
478
479		return true;
480	}
481	
482	public function update()
483	{
484		global $DB;
485		global $events;
486		global $user;
487
488        if(!is_null($user))
489        {
490            if($user->permission("products.edit") == 'false' && $this->author != $user->id)
491                throw new Exception(t(610, "Sorry, you are not allowed to execute this function."));
492
493            if( !structure::category_allowed($this->category) )
494                throw new Exception(t(610, "Sorry, you are not allowed to execute this function."));
495        }
496
497		$this->date_modified = core_time();
498
499        $groups = '';
500        if(is_array($this->groups))
501        {
502            $this->groups = array_unique($this->groups); // remove duplicates
503            $this->groups = array_filter($this->groups); // remove empty
504            if(!empty($this->groups))
505                $groups = 'g'.implode(',g', $this->groups);
506        }
507
508        if($groups == 'g')
509            $groups = '';
510
511        $ok = $DB->execute(' 
512            UPDATE nv_products
513            SET 
514                  category = :category,
515                  type = :type,
516                  template = :template,
517                  author = :author,
518                  brand = :brand,
519                  date_to_display = :date_to_display,
520                  date_published = :date_published,
521                  date_unpublish = :date_unpublish,
522                  date_modified = :date_modified,
523                  sku = :sku,
524                  barcode = :barcode,
525                  base_price = :base_price,
526                  base_price_currency = :base_price_currency,
527                  tax_class = :tax_class,
528                  tax_value = :tax_value,
529                  cost = :cost,
530                  cost_currency = :cost_currency,
531                  sale_price = :sale_price,
532                  sale_price_currency = :sale_price_currency,
533                  sale_begin_date = :sale_begin_date,
534                  sale_end_date = :sale_end_date,
535                  width = :width,
536                  height = :height,
537                  depth = :depth,
538                  size_unit = :size_unit,
539                  weight = :weight,
540                  weight_unit = :weight_unit,
541                  inventory = :inventory,
542                  stock_available = :stock_available,
543                  options = :options,
544                  galleries = :galleries,
545                  comments_enabled_to = :comments_enabled_to,
546                  comments_moderator = :comments_moderator,
547                  access = :access,
548                  groups = :groups,
549                  permission = :permission,
550                  views = :views,
551                  votes = :votes,
552                  score = :score,
553                  position = :position
554            WHERE id = :id
555              AND website = :website',
556            array(
557                ":id" => $this->id,
558                ":website" => $this->website,
559                ":category" => value_or_default($this->category, 0),
560                ":template" => value_or_default($this->template, ''),
561                ":type" => value_or_default($this->type, 0),
562                ":brand" => value_or_default($this->brand, 0),
563                ":date_to_display" => intval($this->date_to_display),
564                ":date_published" => intval($this->date_published),
565                ":date_unpublish" => intval($this->date_unpublish),
566                ":date_modified" => $this->date_modified,
567                ":sku" =>  value_or_default($this->sku, ''),
568                ":barcode" =>  value_or_default($this->barcode, ''),
569                ":base_price" =>  value_or_default($this->base_price, 0),
570                ":base_price_currency" =>  value_or_default($this->base_price_currency, ""),
571                ":tax_class" =>  value_or_default($this->tax_class, "included"),
572                ":tax_value" =>  value_or_default($this->tax_value, 0),
573                ":cost" =>  value_or_default($this->cost, 0),
574                ":cost_currency" =>  value_or_default($this->cost_currency, ""),
575                ":sale_price" => value_or_default($this->sale_price, 0),
576                ":sale_price_currency" => value_or_default($this->sale_price, ""),
577                ":sale_begin_date" => intval($this->sale_begin_date),
578                ":sale_end_date" => intval($this->sale_end_date),
579                ":width" => value_or_default($this->width, 0),
580                ":height" => value_or_default($this->height, 0),
581                ":depth" => value_or_default($this->depth, 0),
582                ":size_unit" => value_or_default($this->size_unit, 'cm'),
583                ":weight" => value_or_default($this->weight, 0),
584                ":weight_unit" => value_or_default($this->weight_unit, 'kg'),
585                ":inventory" => value_or_default($this->inventory, 0),
586                ":stock_available" => value_or_default($this->stock_available, 0),
587                ":options" => json_encode($this->options),
588                ":author" => value_or_default($this->author, 0),
589                ":galleries" => serialize($this->galleries),
590                ":comments_enabled_to" => value_or_default($this->comments_enabled_to, 0),
591                ":comments_moderator" => value_or_default($this->comments_moderator, 0),
592                ":access" => value_or_default($this->access, 0),
593                ":groups" => $groups,
594                ":permission" => value_or_default($this->permission, 0),
595                ":views" => $this->views,
596                ":votes" => $this->votes,
597                ":score" => $this->score,
598                ":position" => value_or_default($this->position, 0)
599            )
600        );
601		
602		if(!$ok)
603			throw new Exception($DB->get_last_error());
604
605		webdictionary::save_element_strings('product', $this->id, $this->dictionary, $this->website);
606		webdictionary_history::save_element_strings('product', $this->id, $this->dictionary, false, $this->website);
607   		path::saveElementPaths('product', $this->id, $this->paths, $this->website);
608
609        $events->trigger(
610            'product',
611            'save',
612            array(
613                'product' => $this
614            )
615        );
616
617		return true;
618	}
619
620	public function load_template()
621	{
622		$template = new template();
623        $template->load($this->template);
624		return $template;
625	}
626	
627	public function property($property_name, $raw=false)
628	{
629		// load properties if not already done
630		if(empty($this->properties))
631            $this->properties = property::load_properties('product', $this->template, 'product', $this->id);
632
633		for($p=0; $p < count($this->properties); $p++)
634		{
635			if($this->properties[$p]->name==$property_name || $this->properties[$p]->id==$property_name)
636			{
637				if($raw)
638					$out = $this->properties[$p]->value;
639				else
640					$out = $this->properties[$p]->value;
641					
642				break;
643			}
644		}
645		
646		return $out;
647	}
648
649	public function property_exists($property_name)
650	{
651		// load properties if not already done
652        if(empty($this->properties))
653            $this->properties = property::load_properties('product', $this->template, 'product', $this->id);
654
655		for($p=0; $p < count($this->properties); $p++)
656		{
657			if($this->properties[$p]->name==$property_name || $this->properties[$p]->id==$property_name)
658				return true;
659		}
660		return false;
661	}
662
663    public function property_definition($property_name)
664	{
665	    $out = "";
666
667		// load properties if not already done
668        if(empty($this->properties))
669            $this->properties = property::load_properties('product', $this->template, 'product', $this->id);
670
671		for($p=0; $p < count($this->properties); $p++)
672		{
673			if($this->properties[$p]->name==$property_name || $this->properties[$p]->id==$property_name)
674			{
675                $out = $this->properties[$p];
676                break;
677			}
678		}
679
680		return $out;
681	}
682
683    public function link($lang)
684    {
685        $url = $this->paths[$lang];
686	    if(empty($url))
687		    $url = '/product/'.$this->id;
688        $url = nvweb_prepare_link($url);
689        return $url;
690    }
691
692    public function comments_count()
693    {
694        global $DB;
695
696        if(empty($this->_comments_count))
697        {
698            $DB->query('
699                SELECT COUNT(*) as total
700                      FROM nv_comments
701                     WHERE website = ' . protect($this->website) . '
702                       AND object_type = "product"
703                       AND object_id = ' . protect($this->id) . '
704                       AND status = 0'
705            );
706
707            $out = $DB->result('total');
708            $this->_comments_count = $out[0];
709        }
710
711        return $this->_comments_count;
712    }
713
714    public static function reorder($order)
715    {
716        global $DB;
717		global $website;
718
719		$items = explode("#", $order);
720
721		for($i=0; $i < count($items); $i++)
722		{
723			if(empty($items[$i])) continue;
724
725			$ok = $DB->execute('
726              UPDATE nv_products
727				 SET position = '.($i+1).'
728			   WHERE id = '.$items[$i].' AND 
729			         website = '.$website->id
730            );
731
732			if(!$ok)
733			    return array("error" => $DB->get_last_error());
734		}
735
736		return true;
737    }
738	
739	public function quicksearch($text)
740	{
741		global $DB;
742		global $website;
743
744		$where = '';
745		$search = explode(" ", $text);
746		$search = array_filter($search);
747		sort($search);
748		foreach($search as $text)
749		{
750			$like = ' LIKE '.protect('%'.$text.'%');
751
752			// we search for the IDs at the dictionary NOW (to avoid inefficient requests)
753			$DB->query('SELECT DISTINCT (nvw.node_id)
754						 FROM nv_webdictionary nvw
755						 WHERE nvw.node_type = "product"
756						   AND nvw.website = '.$website->id.'
757						   AND nvw.text '.$like, 'array');
758
759			$dict_ids = $DB->result("node_id");
760
761			// all columns to look for
762			$cols[] = 'p.id' . $like;
763			if(!empty($dict_ids))
764				$cols[] = 'p.id IN ('.implode(',', $dict_ids).')';
765
766			$where .= ' AND ( ';
767			$where .= implode( ' OR ', $cols);
768			$where .= ')';
769		}
770		
771		return $where;
772	}
773
774    public function backup($type='json')
775    {
776        global $DB;
777        global $website;
778
779        $out = array();
780        $DB->query('SELECT * FROM nv_products WHERE website = '.protect($website->id), 'object');
781
782        if($type='json')
783            $out = json_encode($DB->result());
784
785        return $out;
786    }
787
788    public static function size_units()
789    {
790        $size_units = array(
791            'cm', 'm', 'mm', 'in'
792        );
793        return $size_units;
794    }
795
796    public static function weight_units()
797    {
798        $weight_units = array(
799            'g', 'kg', 'lb'
800        );
801        return $weight_units;
802    }
803
804    public static function currencies()
805    {
806        $currencies = array(
807            'euro' => '€',
808            'dollar' => '$'
809        );
810
811        return $currencies;
812    }
813
814    public static function tax_classes()
815    {
816        $tax_classes = array(
817            'included' => t(679, "Included"),
818            'free' => t(100, "Free"),
819            'custom' => "(". t(680, "Custom") . ")"
820        );
821
822        return $tax_classes;
823    }
824
825	public static function __set_state(array $obj)
826	{
827		$tmp = new product();
828		foreach($obj as $key => $val)
829			$tmp->$key = $val;
830
831		return $tmp;
832	}
833	
834}
835?>