public function install()
{
$iaDb =& $this->iaDb;
$this->iaCore->startHook('phpExtrasInstallBefore', array('extra' => $this->itemData['name']));
$extrasList = array();
$array = $iaDb->all(array('id', 'name', 'version'), "`status` = 'active'", null, null, self::getTable());
foreach ($array as $item) {
$extrasList[$item['name']] = $item;
}
// TODO: check for relations and deactivate all needed extras
if ($this->itemData['requirements']) {
$messages = array();
foreach ($this->itemData['requirements'] as $requirement) {
if ($requirement['min'] || $requirement['max']) {
$min = $max = false;
if (isset($extrasList[$requirement['name']])) {
$info = $extrasList[$requirement['name']];
$min = $requirement['min'] ? version_compare($requirement['min'], $info['version'], '<=') : true;
$max = $requirement['max'] ? version_compare($requirement['max'], $info['version'], '>=') : true;
}
if (!$max || !$min) {
$ver = '';
if ($requirement['min']) {
$ver .= $requirement['min'];
}
if ($requirement['max']) {
if ($requirement['min']) {
$ver .= '-';
}
$ver .= $requirement['max'];
}
$values = array(':extra' => $requirement['type'], ':name' => $requirement['name'], ':version' => $ver);
$messages[] = iaLanguage::getf('required_extras_error', $values);
$this->error = true;
} else {
// TODO: add relations in database to deactivate when parent is uninstalled
}
}
}
if ($this->error) {
$this->setMessage(implode('<br />', $messages));
return false;
}
}
$this->uninstall($this->itemData['name']);
if (false !== stristr('update', $this->itemData['name'])) {
$this->isUpdate = true;
}
if ($this->itemData['groups']) {
$iaDb->setTable('admin_pages_groups');
$maxOrder = $iaDb->getMaxOrder();
foreach ($this->itemData['groups'] as $block) {
$iaDb->insert($block, array('order' => ++$maxOrder));
}
$iaDb->resetTable();
}
if ($this->itemData['pages']['admin']) {
$iaDb->setTable('admin_pages');
$order = (int) $iaDb->one('MAX(`order`)', "`menus` IN ('menu')");
$order = max($order, 1);
foreach ($this->itemData['pages']['admin'] as $page) {
if (is_null($page['order'])) {
$order += 5;
$page['order'] = $order;
}
if ($page['group']) {
$this->_menuGroups[] = $page['group'];
}
$page['group'] = $this->_lookupGroupId($page['group']);
$iaDb->insert($page);
}
$iaDb->resetTable();
}
if ($this->itemData['actions']) {
$iaDb->setTable('admin_actions');
foreach ($this->itemData['actions'] as $action) {
$action['name'] = strtolower(str_replace(' ', '_', $action['name']));
if ($action['name'] && !$iaDb->exists('`name` = :name', array('name' => $action['name']))) {
$action['order'] = empty($action['order']) || !is_numeric($action['order']) ? $iaDb->getMaxOrder() + 1 : $action['order'];
$iaDb->insert($action);
}
}
$iaDb->resetTable();
}
if ($this->itemData['phrases']) {
$this->_processPhrases($this->itemData['phrases']);
}
if ($this->itemData['config_groups']) {
$iaDb->setTable(iaCore::getConfigGroupsTable());
$maxOrder = $iaDb->getMaxOrder();
foreach ($this->itemData['config_groups'] as $config) {
$iaDb->insert($config, array('order' => ++$maxOrder));
}
$iaDb->resetTable();
}
if ($this->itemData['objects']) {
$iaDb->setTable('acl_objects');
foreach ($this->itemData['objects'] as $obj) {
if ($obj['title']) {
$key = ($obj['object'] == $obj['pre_object'] ? '' : $obj['pre_object'] . '-') . $obj['object'] . '--' . $obj['action'];
iaLanguage::addPhrase($key, $obj['title'], null, $this->itemData['name'], iaLanguage::CATEGORY_COMMON, false);
unset($obj['title']);
}
$iaDb->insert($obj);
}
$iaDb->resetTable();
}
if ($this->itemData['permissions']) {
$iaDb->setTable('acl_privileges');
foreach ($this->itemData['permissions'] as $permission) {
$iaDb->insert($permission);
}
$iaDb->resetTable();
}
if ($this->itemData['config']) {
$iaDb->setTable('config');
$maxOrder = $iaDb->getMaxOrder();
foreach ($this->itemData['config'] as $config) {
$iaDb->insert($config, array('order' => ++$maxOrder));
}
$iaDb->resetTable();
}
if ($this->itemData['pages']['custom'] && $this->itemData['type'] == self::TYPE_PACKAGE) {
$iaDb->setTable('items_pages');
foreach ($this->itemData['pages']['custom'] as $page) {
$iaDb->insert(array('page_name' => $page['name'], 'item' => $page['item']));
}
$iaDb->resetTable();
}
$iaBlock = $this->iaCore->factory('block', iaCore::ADMIN);
$extraPages = array();
if ($this->itemData['pages']['front']) {
$pageGroups = $iaDb->keyvalue(array('name', 'id'), null, 'admin_pages_groups');
$iaDb->setTable('pages');
$maxOrder = $iaDb->getMaxOrder();
$existPages = $iaDb->keyvalue(array('name', 'id'));
foreach ($this->itemData['pages']['front'] as $page) {
if (!isset($existPages[$page['name']])) {
if (self::TYPE_PACKAGE == $this->itemData['type'] && $page['fields_item']) {
$iaDb->insert(array('page_name' => $page['name'], 'item' => $page['fields_item']), null, 'items_pages');
}
$title = isset($page['title']) && $page['title'] ? $page['title'] : false;
$blocks = isset($page['blocks']) && $page['blocks'] ? $page['blocks'] : false;
$menus = isset($page['menus']) && $page['menus'] ? explode(',', $page['menus']) : array();
$contents = isset($page['contents']) && $page['contents'] ? $page['contents'] : false;
unset($page['title'], $page['blocks'], $page['menus'], $page['contents']);
$page['group'] = $pageGroups[$page['group']];
$pageId = $iaDb->insert($page, array('order' => ++$maxOrder, 'last_updated' => iaDb::FUNCTION_NOW));
empty($title) || $this->_addPhrase('page_title_' . $page['name'], $title, iaLanguage::CATEGORY_PAGE);
// TODO: should be handled by iaBlock
if ($blocks) {
$blocks = $iaDb->keyvalue(array('name', 'id'), "`name` IN ('" . implode("','", $blocks) . "')", iaBlock::getTable(), 0, 1);
foreach ($blocks as $blockId) {
$iaDb->insert(array('object_type' => 'blocks', 'object' => $blockId, 'page_name' => $page['name']), null, 'objects_pages');
}
}
if (!is_int($page['group'])) {
$page['group'] = $this->_lookupGroupId($page['group']);
}
if ($menus) {
$iaDb->setTable(iaBlock::getTable());
$added = array();
$items = array();
$menusData = $iaDb->keyvalue(array('id', 'name'), "`type` = 'menu'");
$db = false;
foreach ($menusData as $id => $name) {
if (in_array($name, $menus)) {
$added[] = $name;
$items[] = array('parent_id' => 0, 'menu_id' => $id, 'el_id' => $pageId . '_' . iaUtil::generateToken(4), 'level' => 0, 'page_name' => $page['name']);
$db = true;
$this->iaCore->iaCache->remove('menu_' . $id . '.inc');
}
}
if ($db) {
$iaDb->insert($items, null, iaBlock::getMenusTable());
}
foreach ($menus as $val) {
if (!in_array($val, $added)) {
$menuItem = array('type' => iaBlock::TYPE_MENU, 'status' => iaCore::STATUS_ACTIVE, 'position' => 'left', 'collapsible' => true, 'title' => $this->itemData['info']['title'], 'extras' => $this->itemData['name'], 'name' => $this->itemData['name'], 'sticky' => true, 'removable' => false);
$menuItem['id'] = $iaBlock->insert($menuItem);
$contents = array('parent_id' => 0, 'menu_id' => $menuItem['id'], 'el_id' => $pageId . '_' . iaUtil::generateToken(5), 'level' => 0, 'page_name' => $page['name']);
$iaDb->insert($contents, null, iaBlock::getMenusTable());
}
}
$iaDb->resetTable();
}
empty($contents) || $this->_addPhrase('page_content_' . $page['name'], $contents, iaLanguage::CATEGORY_PAGE);
$extraPages[] = $page['name'];
}
}
$iaDb->resetTable();
}
if ($this->itemData['blocks']) {
$iaBlock = $this->iaCore->factory('block', iaCore::ADMIN);
foreach ($this->itemData['blocks'] as $block) {
$iaBlock->insert($block);
}
}
if ($this->itemData['hooks']) {
$iaDb->setTable('hooks');
$maxOrder = $iaDb->getMaxOrder();
foreach ($this->itemData['hooks'] as $hook) {
$array = explode(',', $hook['name']);
foreach ($array as $hookName) {
if (trim($hookName)) {
$hook['name'] = $hookName;
if (isset($hook['code']) && $hook['code']) {
$hook['code'] = str_replace('{extras}', $this->itemData['name'], $hook['code']);
}
$rawValues = array();
if (!isset($hook['order'])) {
$rawValues['order'] = ++$maxOrder;
}
$iaDb->insert($hook, $rawValues);
}
}
}
$iaDb->resetTable();
}
if ($this->itemData['usergroups']) {
$this->iaCore->factory('acl');
$iaDb->setTable(iaUsers::getUsergroupsTable());
foreach ($this->itemData['usergroups'] as $item) {
if (!$iaDb->exists('`name` = :name', array('name' => $item['name']))) {
$configs = $item['configs'];
$permissions = $item['permissions'];
$groupId = $iaDb->insert(array('extras' => $item['extras'], 'name' => $item['name'], 'system' => true, 'assignable' => $item['assignable'], 'visible' => $item['visible']));
// update language records
$this->_addPhrase('usergroup_' . $item['name'], $item['title']);
$iaDb->setTable(iaCore::getCustomConfigTable());
$iaDb->delete('`type` = :type AND `type_id` = :id', null, array('type' => iaAcl::GROUP, 'id' => $groupId));
foreach ($configs as $config) {
$data = array('name' => $config['name'], 'value' => $config['value'], 'type' => iaAcl::GROUP, 'type_id' => $groupId, 'extras' => $this->itemData['name']);
$iaDb->insert($data);
}
$iaDb->resetTable();
$iaDb->setTable('acl_privileges');
$iaDb->delete('`type` = :type AND `type_id` = :id', null, array('type' => iaAcl::GROUP, 'id' => $groupId));
foreach ($permissions as $permission) {
$data = array('object' => $permission['object'], 'object_id' => $permission['object_id'], 'action' => $permission['action'], 'access' => $permission['access'], 'type' => iaAcl::GROUP, 'type_id' => $groupId, 'extras' => $permission['extras']);
$iaDb->insert($data);
}
$iaDb->resetTable();
}
}
$iaDb->resetTable();
}
$extraEntry = array_merge($this->itemData['info'], array('name' => $this->itemData['name'], 'type' => $this->itemData['type']));
unset($extraEntry['date']);
if ($this->itemData['sql']['uninstall']) {
$extraEntry['uninstall_sql'] = serialize($this->itemData['sql']['uninstall']);
}
if ($this->itemData['code']['uninstall']) {
$extraEntry['uninstall_code'] = $this->itemData['code']['uninstall'];
}
if ($this->itemData['sql']['install']) {
$this->_processQueries($this->itemData['sql']['install']);
}
if (self::TYPE_PACKAGE == $this->itemData['type']) {
$extraEntry['url'] = $this->_url;
}
if ($this->itemData['items']) {
$extraEntry['items'] = serialize($this->itemData['items']);
$iaDb->setTable('items');
foreach ($this->itemData['items'] as $item) {
$iaDb->insert(array_merge($item, array('package' => $this->itemData['name'])));
}
$iaDb->resetTable();
}
$this->iaCore->factory('field');
$fieldGroups = $iaDb->keyvalue('CONCAT(`item`, `name`) `key`, `id`', null, iaField::getTableGroups());
if ($this->itemData['item_field_groups']) {
$maxOrder = $iaDb->getMaxOrder(iaField::getTableGroups());
foreach ($this->itemData['item_field_groups'] as $item) {
$item['order'] || ($item['order'] = ++$maxOrder);
if ($item['title'] && !$iaDb->exists("`key` = 'fieldgroup_{$item['name']}' AND `code`='" . $this->iaView->language . "'", null, iaLanguage::getTable())) {
$this->_addPhrase('fieldgroup_' . $item['name'], $item['title']);
}
unset($item['title']);
$description = 'fieldgroup_description_' . $item['item'] . '_' . $item['name'];
if (!$iaDb->exists('`key` = :key AND `code` = :language', array('key' => $description, 'language' => $this->iaView->language), iaLanguage::getTable())) {
// insert fieldgroup description
iaLanguage::addPhrase($description, $item['description'], null, $this->itemData['name'], iaLanguage::CATEGORY_COMMON, false);
}
unset($item['description']);
$fieldGroups[$item['item'] . $item['name']] = $iaDb->insert($item, null, iaField::getTableGroups());
}
}
if ($this->itemData['item_fields']) {
$iaDb->setTable(iaField::getTable());
$maxOrder = $iaDb->getMaxOrder(iaField::getTable());
foreach ($this->itemData['item_fields'] as $item) {
if (!$iaDb->exists('`item` = :item AND `name` = :name', array('item' => $item['item'], 'name' => $item['name']))) {
$item['order'] || ($item['order'] = ++$maxOrder);
$item['fieldgroup_id'] = isset($fieldGroups[$item['item'] . $item['group']]) ? $fieldGroups[$item['item'] . $item['group']] : 0;
$this->_addPhrase('field_' . $item['name'], $item['title']);
unset($item['group'], $item['title']);
if (is_array($item['numberRangeForSearch'])) {
foreach ($item['numberRangeForSearch'] as $num) {
$this->_addPhrase('field_' . $item['name'] . '_range_' . $num, $num, iaLanguage::CATEGORY_FRONTEND);
}
}
unset($item['numberRangeForSearch']);
if ('dependent' == $item['relation']) {
$iaDb->setTable(iaField::getTableRelations());
foreach (explode(';', $item['parent']) as $parent) {
$list = explode(':', $parent);
if (2 == count($list)) {
list($fieldName, $fieldValues) = $list;
foreach (explode(',', $fieldValues) as $fieldValue) {
$entryData = array('field' => $fieldName, 'element' => $fieldValue, 'child' => $item['name'], 'item' => $item['item'], 'extras' => $this->itemData['name']);
$iaDb->insert($entryData);
}
}
}
$iaDb->resetTable();
}
unset($item['parent']);
if (is_array($item['values'])) {
foreach ($item['values'] as $key => $value) {
$key = sprintf('field_%s_%s', $item['name'], $key);
$this->_addPhrase($key, $value);
}
if ($item['default']) {
// TODO: multiple default values for checkboxes should be implemented
if (!in_array($item['default'], array_keys($item['values']))) {
$item['default'] = array_search($item['default'], $item['values']);
}
}
$item['values'] = implode(',', array_keys($item['values']));
}
$fieldPages = $item['item_pages'] ? $item['item_pages'] : array();
$tableName = $item['table_name'];
$className = $item['class_name'];
unset($item['item_pages'], $item['table_name'], $item['class_name']);
$fieldId = $iaDb->insert($item);
$item['table_name'] = $tableName;
$item['class_name'] = $className;
if ($fieldPages) {
foreach ($fieldPages as $pageName) {
if (trim($pageName) != '') {
$iaDb->insert(array('page_name' => $pageName, 'field_id' => $fieldId, 'extras' => $this->itemData['name']), null, iaField::getTablePages());
}
}
}
$iaDb->setTable($tableName);
$tableFields = $iaDb->describe();
$isExist = false;
foreach ($tableFields as $f) {
if ($f['Field'] == $item['name']) {
$isExist = true;
break;
}
}
if (!$isExist) {
$this->_addAlter($item);
}
$iaDb->resetTable();
} else {
$stmt = '`item` = :item AND `name` = :name';
$iaDb->bind($stmt, $item);
$iaDb->update(null, $stmt, array('extras' => "CONCAT(`extras`, ',', '" . $this->itemData['name'] . "')"));
}
}
$iaDb->resetTable();
}
$rollbackData = array();
if ($this->itemData['changeset']) {
$tablesMapping = array('block' => 'blocks', 'field' => 'fields', 'menu' => 'blocks');
foreach ($this->itemData['changeset'] as $entry) {
if (!isset($tablesMapping[$entry['type']])) {
continue;
}
switch ($entry['type']) {
case 'field':
list($fieldName, $itemName) = explode('-', $entry['name']);
if (empty($fieldName) || empty($itemName)) {
continue;
}
$stmt = iaDb::printf("`name` = ':name' AND `item` = ':item'", array('name' => $fieldName, 'item' => $itemName));
break;
default:
$stmt = iaDb::printf("`name` = ':name'", $entry);
}
$tableName = $tablesMapping[$entry['type']];
$name = $entry['name'];
unset($entry['type'], $entry['name']);
$entryData = $iaDb->row('`' . implode('`,`', array_keys($entry)) . '`', $stmt, $tableName);
if ($iaDb->update($entry, $stmt, null, $tableName)) {
$rollbackData[$tableName][$name] = $entryData;
}
}
}
$extraEntry['rollback_data'] = empty($rollbackData) ? '' : serialize($rollbackData);
if (self::TYPE_PLUGIN == $this->itemData['type']) {
$extraEntry['removable'] = !in_array($this->itemData['name'], $this->_builtinPlugins);
}
if (!$this->isUpdate) {
$this->iaCore->startHook('phpExtrasInstallBeforeSql', array('extra' => $this->itemData['name'], 'data' => &$this->itemData['info']));
$iaDb->insert($extraEntry, array('date' => iaDb::FUNCTION_NOW), self::getTable());
}
$this->_processCategory($extraEntry);
if ($this->itemData['code']['install']) {
$this->_runPhpCode($this->itemData['code']['install']);
}
if ($this->itemData['cron_jobs']) {
$this->iaCore->factory('cron');
foreach ($this->itemData['cron_jobs'] as $job) {
$job['extras'] = $this->itemData['name'];
$iaDb->insert($job, null, iaCron::getTable());
}
}
$this->iaCore->startHook('phpExtrasInstallAfter', array('extra' => $this->itemData['name']));
$this->iaCore->factory('cache')->clearAll();
return true;
}