<?php
/**
 * FW Food menu 5.1.1
 * @copyright (C) 2020 Fastw3b
 * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL
 * @link http://www.fastw3b.net/ Official website
 **/

defined( '_JEXEC' ) or die( 'Restricted access' );

class MenuModelCategory extends JModelLegacy {
	function _collectWhere() {
		$where = array();
		$db = JFactory::getDBO();
        $app = JFactory::getApplication();
		if ($search = $app->input->getString('search')) {
			$search = $db->escape(trim($search));
			if ($buff = $app->triggerEvent('onGetCategoryNameSearch', array('com_fwfoodmenu', $search))) {
				foreach ($buff as $row) {
					if ($row) {
						$where[] = $row;
					}
				}
			} else {
				$where[] = "(c.name LIKE '%${search}%' OR c.description LIKE '%${search}%')";
			}
		}
		if ($category = (int)$app->input->getInt('category')) {
			$where[] = 'c.parent = '.$category;
		}
		if ($state = $app->input->getCmd('state')) {
			if ($state == 'published') {
				$where[] = 'c.published = 1';
			} elseif ($state == 'unpublished') {
				$where[] = 'c.published = 0';
			}
		}
		return $where?(' WHERE '.implode(' AND ', $where)):'';
	}
	function loadList() {
        $app = JFactory::getApplication();
		$input = $app->input;
		$where = $this->_collectWhere();
		$db = JFactory::getDBO();
		$db->setQuery('SELECT c.id FROM `#__fwfoodmenu_category` AS c WHERE c.parent <> 0 AND NOT EXISTS(SELECT * FROM `#__fwfoodmenu_category` AS cc WHERE cc.id = c.parent)');
		if ($ids = $db->loadColumn()) {
			$db->setQuery('UPDATE `#__fwfoodmenu_category` SET parent = 0  WHERE id IN ('.implode(',', $ids).')');
			$db->execute();
		}
		$db->setQuery('
SELECT
    c.*,
	c.name AS treename,
	(SELECT COUNT(*) FROM #__fwfoodmenu_menu AS m WHERE m.category_id = c.id) AS _menu_qty
FROM
    #__fwfoodmenu_category AS c
'.$where.'
ORDER BY
	c.parent,
	c.ordering'
		);

		if ($rows = $db->loadObjectList()) {
			$ids = array();
			foreach ($rows as $i=>$row) {
				$ids[] = $row->id;
				$rows[$i]->params = new JRegistry($row->params);
			}
			JFactory::getApplication()->triggerEvent('onCalculateCategoryListExtraFields', array('com_fwfoodmenu', &$rows, $ids));
			if ($where) {
				return $rows;
			} else {
				$children = array();
				foreach ($rows as $v) {
					$pt = $v->parent;
					$list = @$children[$pt] ? $children[$pt] : array();
					array_push( $list, $v );
					$children[$pt] = $list;
				}
				$levellimit = 10;
				$list = JHTML::_('fwfCategory.treerecurse', 0, '', array(), $children, max( 0, $levellimit-1 ) );
				if ($limit = $input->getInt('limit', $app->getCfg('list_limit'))) $list = array_slice($list, (int)$input->getInt('limitstart'), $limit);
				return $list;
			}
		}
	}
	function loadQty() {
		$db = JFactory::getDBO();
        $db->setQuery('
SELECT
    COUNT(*)
FROM
    #__fwfoodmenu_category AS c
'.$this->_collectWhere());
        return $db->loadResult();
	}
	function getPagination() {
        $app = JFactory::getApplication();
		$input = $app->input;
        jimport('joomla.html.pagination');
		return new JPagination(
			$this->loadQty(),
			$input->getInt('limitstart'),
			$input->getInt('limit', $app->getCfg('list_limit'))
		);
	}
	function loadObject() {
        $category = $this->getTable('category');
		$input = JFactory::getApplication()->input;
        if (($ids = (array)$input->getVar('cid') and $id = JArrayHelper::getValue($ids, 0)) or $id = $input->getInt('id', 0)) {
            $category->load($id);
        }
		if (!$category->id) {
			$category->params = new JRegistry();
		}
        return $category;
	}
    function save() {
        $category = $this->getTable('category');
		$input = JFactory::getApplication()->input;
        if ($id = $input->getInt('oid')) {
			$category->load($id);
		}

        if ($category->bind($input->getArray(array(), null, 'RAW'), array('id')) and $category->check() and $category->store()) {
            $this->setError(JText::_('FWFM_CATEGORY_STORED_SUCCESSFULLY'));
            return $category->id;
        } else
        	$this->setError($category->getError());
    }
	function save2copy() {
		$app = JFactory::getApplication();
		$input = $app->input;
		$id = $input->getInt('oid');

		$category = $this->getTable('category');
		if ($category->bind($input->getArray(array(), null, 'RAW'), array('id', 'published', 'ordering'))) {
			$category->id = 0;
			$category->ordering = 0;
			$category->published = 0;
			$category->name .= ' (copy)';
			if ($category->check() and $category->store()) {
				$app->triggerEvent('onSave2copyCategoryExtraFields', array('com_fwfoodmenu', $category, $id));
				$this->setError(JText::_('FWFM_CATEGORY_COPIED'));
				return $category->id;
			} else $this->setError($category->getError());
		}
        $this->setError(JText::_('FWFM_NO_CATEGORY_ID_PASSED_TO_REMOVE'));
	}
    function copy() {
		$app = JFactory::getApplication();
		$input = $app->input;
        if ($cid = (array)$input->getVar('cid')) {
            $category = $this->getTable('category');
            foreach ($cid as $id) {
                if ($category->load($id)) {
					$category->id = 0;
					$category->ordering = 0;
					$category->published = 0;
					$category->name .= ' (copy)';
					if ($category->check() and $category->store()) {
						$app->triggerEvent('onCopyCategoryExtraFields', array('com_fwfoodmenu', $category, $id));
					} else {
						$this->setError($category->getError());
					}
				}
            }
            $this->setError(JText::_('FWFM_CATEGORY_COPIED'));
            return true;
        }
        $this->setError(JText::_('FWFM_NO_CATEGORY_ID_PASSED_TO_REMOVE'));
    }
    function remove() {
		$input = JFactory::getApplication()->input;
        if ($cid = (array)$input->getVar('cid')) {
            $category = $this->getTable('category');
            foreach ($cid as $id) {
                $category->delete($id);
            }
            $this->setError(JText::_('FWFM_CATEGORY_REMOVED'));
            return true;
        }
        $this->setError(JText::_('FWFM_NO_CATEGORY_ID_PASSED_TO_REMOVE'));
    }
    function saveorder() {
		$input = JFactory::getApplication()->input;
        $cid = $input->getVar('cid');
        $order = $input->getVar('order');

        if (is_array($cid) and is_array($order) and count($cid) and count($cid) == count($order)) {
			JArrayHelper::toInteger($cid, 0);
            $db = JFactory::getDBO();
            foreach ($cid as $num=>$id) {
				$odering = (int)JArrayHelper::getValue($order, $num);
				$db->setQuery('UPDATE `#__fwfoodmenu_category` SET ordering = '.$odering.' WHERE id = '.(int)$id);
				$db->execute();
            }
            $category = $this->getTable('category');
			$db->setQuery('SELECT DISTINCT `parent` FROM `#__fwfoodmenu_category` WHERE id IN ('.implode(',', $cid).')');
			$pids = $db->loadColumn();
			foreach ($pids as $pid) {
				$category->reorder('parent = '.(int)$pid);
			}
            return true;
        }
    }
    function orderdown() {
		$input = JFactory::getApplication()->input;
        if ($cid = (array)$input->getVar('cid') and $id = JArrayHelper::getValue($cid, 0)) {
            $category = $this->getTable('category');
            if ($category->load($id)) {
				$category->move(1, 'parent = '.(int)$category->parent);
			}
            return true;
        }
    }
    function orderup() {
		$input = JFactory::getApplication()->input;
        if ($cid = (array)$input->getVar('cid') and $id = JArrayHelper::getValue($cid, 0)) {
            $category = $this->getTable('category');
			if ($category->load($id)) {
				$category->move(-1, 'parent = '.(int)$category->parent);
			}
            return true;
        }
    }
    function publish() {
		$input = JFactory::getApplication()->input;
        if ($cid = (array)$input->getVar('cid')) {
            $category = $this->getTable('category');
            $category->publish($cid, 1);
            $this->setError(JText::_('FWFM_CATEGORY_PUBLISHED'));
            return true;
        }
        $this->setError(JText::_('FWFM_NO_CATEGORY_ID_PASSED_TO_PUBLISH'));
    }
    function unpublish() {
		$input = JFactory::getApplication()->input;
        if ($cid = (array)$input->getVar('cid')) {
            $category = $this->getTable('category');
            $category->publish($cid, 0);
            $this->setError(JText::_('FWFM_CATEGORY_UNPUBLISHED'));
            return true;
        }
        $this->setError(JText::_('FWFM_NO_CATEGORY_ID_PASSED_TO_UNPUBLISH'));
    }
	function quickCategories() {
		$input = JFactory::getApplication()->input;
		if ($text = $input->getString('text')) {
			$db = JFactory::getDBO();
			$data = explode("\n", str_replace("\r", '', $text));
			$parents = array(0);
			$parent = 0;
			$prev_qty = 0;
			$prev_id = 0;
			$updated = $added = 0;

			$parent = (int)$input->getInt('category');

			foreach ($data as $name) {
				$buff = explode('=', $name, 3);
				$name = trim($buff[0]);
				if (empty($name)) {
					continue;
				}
				$qty = 0;
				if (preg_match('#^([-]+)#', $name, $match)) {
					$qty = strlen($match[1]);
					$name = ltrim($name, '- ');
				}
				if ($qty > $prev_qty) {
					if ($prev_id) {
						$parent = $prev_id;
						$parents[] = $prev_id;
						$prev_qty = $qty;
					} else {
						$this->setError(JText::_('FWFM_NO_TOP_LEVEL'));
						return;
					}
				} elseif ($qty < $prev_qty) {
					for ($i = $qty; $i <= $prev_qty; $i++) {
						if (count($parents) > 1) {
							$parent = array_pop($parents);
						} else {
							$parent = 0;
						}
					}
					$prev_qty = $qty;
				}
				$db->setQuery('
SELECT
	(SELECT id FROM #__fwfoodmenu_category WHERE name = '.$db->quote($name).' AND parent = '.(int)$parent.') AS prev_id,
	(SELECT MAX(ordering) FROM #__fwfoodmenu_category WHERE parent = '.(int)$parent.') AS ordering');
				if ($obj = $db->loadObject()) {
					$prev_id = $obj->prev_id;
					if ($prev_id) {
						$updated++;
					} else {
						$category = $this->getTable('category');
						$data = array(
							'id' => 0,
							'published' => 1,
							'name' => $name,
							'short_description' => empty($buff[1])?'':trim($buff[1]),
							'description' => empty($buff[2])?'':('<p>'.trim($buff[2]).'</p>'),
							'parent' => $parent,
							'ordering' => $obj->ordering + 1,
							'lang' => fwFoodMenuHelper::getLanguage()
						);

						if ($category->bind($data) and $category->check() and $category->store()) {
							$added++;
							$prev_id = $category->id;
						} else {
							$this->setError($category->getError());
						}
					}
				} else {
					$this->setError($db->getError());
				}
			}
			if ($added and $updated) {
				$this->setError(JText::sprintf('FWFM_CATEGORY_QUICK_IMPORT_RESULT_ADDED_EXISTED', $added, $updated));
			} elseif ($added) {
				$this->setError(JText::sprintf('FWFM_CATEGORY_QUICK_IMPORT_RESULT_ADDED', $added));
			} elseif ($updated) {
				$this->setError(JText::sprintf('FWFM_CATEGORY_QUICK_IMPORT_RESULT_EXISTED', $updated));
			} else {
				$this->setError(JText::_('FWFM_CATEGORY_QUICK_IMPORT_RESULT'));
			}
			return true;
		} else $this->setError(JText::_('FWFM_NOTHING_TO_PROCESS'));
	}
	function upload() {
        $category = $this->getTable('category');
		$input = JFactory::getApplication()->input;
        if ($id = $input->getInt('oid')) {
			$category->load($id);
		}

        if ($category->bind($input->getArray(array(), null, 'RAW'), array('id')) and $category->check() and $category->store()) {
            $category->load($category->id);
            return (object)array(
				'id' => $category->id,
				'image' => fwFoodMenuHelper::getImageUrl($category)
			);
        } else {
        	$this->setError($category->getError());
		}
	}
	function deleteImage() {
        $category = $this->getTable('category');
		$input = JFactory::getApplication()->input;
        if ($id = $input->getInt('id') and $category->load($id)) {
			$input->set('delete_image', 1);
			if ($category->check() and $category->store()) {
				$category->load($category->id);
				return (object)array(
					'id' => $category->id,
					'result' => 1,
					'image' => fwFoodMenuHelper::getImageUrl($category)
				);
			} else {
				$this->setError($category->getError());
			}
		} else $this->setError(JText::_('FWFM_CATEGORY_NOT_FOUND'));
	}
	function batch() {
		$app = JFactory::getApplication();

		$input = $app->input;
		if ($cid = (array)$input->getVar('cid')) {
			$db = JFactory::getDBO();
			JArrayHelper::toInteger($cid, 0);
			$changes_requested = false;

			$data = $input->getInt('category_id');
			if ($data >= 0) {
				$ids = array();
				$changes_requested = true;
				/* check parents categories to avoid circular links */
				if ($parents = fwFoodMenuHelper::getParentCategories($data)) {
					$pids = array_keys($parents);
					foreach ($cid as $id) {
						if (!in_array($id, $pids)) {
							$ids[] = $id;
						}
					}
				} else {
					$ids = $cid;
				}
				if ($ids) {
					$db->setQuery('UPDATE `#__fwfoodmenu_category` SET `parent` = '.(int)$data.' WHERE id IN ('.implode(',', $ids).')');
					$db->execute();
				}
			}
			if ($data = $input->getInt('published')) {
				$changes_requested = true;
				$db->setQuery('UPDATE `#__fwfoodmenu_category` SET published = '.(($data == 1)?1:0).' WHERE id IN ('.implode(',', $cid).')');
				$db->execute();
			}

			$app->triggerEvent('onDoBatchCategoriesProcessing', array('com_fwfoodmenu', $cid, &$changes_requested, $this));

			return true;
		}
		$this->setError(JText::_('FWFM_NO_CATEGORY_ID_PASSED_TO_PROCESS'));
	}
}
