Exemplo n.º 1
0
function nvweb_block_group($vars = array())
{
    global $website;
    global $DB;
    global $current;
    global $webgets;
    global $webuser;
    $webget = 'block_group';
    $out = array();
    $bg = new block_group();
    if (!empty($vars['id']) && is_numeric($vars['id'])) {
        $bg->load($vars['id']);
    } else {
        if (!empty($vars['id']) && !is_numeric($vars['id'])) {
            $bg->load_by_code($vars['id']);
        } else {
            if (!empty($vars['code'])) {
                $bg->load_by_code($vars['code']);
            }
        }
    }
    if (!empty($bg->id) && !empty($bg->blocks)) {
        // start rendering every block in the group
        foreach ($bg->blocks as $bgb) {
            // can be a numeric ID or a string representing the block type
            // note: block group blocks are not allowed, as navigate cms does not know the code to generate them
            if (is_numeric($bgb['id'])) {
                $out[] = nvweb_blocks(array('mode' => 'single', 'id' => $bgb['id']));
            } else {
                $out[] = nvweb_blocks(array('type' => $bgb['id']));
            }
        }
    }
    return implode("\n", $out);
}
Exemplo n.º 2
0
    public static function save_properties_from_array($object_type, $object_id, $template, $properties_assoc = array(), $ws = null, $node_uid = "")
    {
        global $DB;
        global $website;
        global $theme;
        if (empty($ws)) {
            $ws = $website;
        }
        $dictionary = array();
        $property_object_type = $object_type;
        // object_type: item, structure, block, block_group_block
        if ($object_type == 'block_group_block') {
            // we have to identify the block subtype: block, block_type, block_group_block or extension_block
            // so we can get its properties definition
            if (!is_numeric($object_id)) {
                // assume there can only be one block group of the same type
                $block_group_id = $DB->query_single('MAX(id)', 'nv_block_groups', ' code = ' . protect($template) . ' AND website = ' . $ws->id);
                $object_id = $block_group_id;
                if (empty($block_group_id)) {
                    $object_id = 0;
                }
            }
            if (!empty($node_uid)) {
                $bg = new block_group();
                $bg->load($object_id);
                for ($b = 0; $b < count($bg->blocks); $b++) {
                    if ($bg->blocks[$b]['uid'] == $node_uid) {
                        $block_id = $bg->blocks[$b]['id'];
                        if ($bg->blocks[$b]['type'] == 'extension') {
                            // an extension block
                            $property_object_type = 'block_group-extension-block';
                            // load the extension, if installed in this instance
                            $extension = new extension();
                            $extension->load($bg->blocks[$b]['extension']);
                            // find the property declaration in the extension definition
                            if (isset($extension->definition->blocks)) {
                                for ($eb = 0; $eb < count($extension->definition->blocks); $eb++) {
                                    if ($extension->definition->blocks[$eb]->id == $block_id) {
                                        $block = $extension->definition->blocks[$eb];
                                        break;
                                    }
                                }
                            } else {
                                // ignore this property, extension is not installed or it does not have the requested block definition
                                continue;
                            }
                        } else {
                            // a block group block
                            $property_object_type = 'block_group_block';
                            $block = block::block_group_block($template, $block_id);
                        }
                        // note: standard blocks don't "embed" their properties in a block group,
                        // they have their own separate values
                        break;
                    }
                }
            } else {
                // compatibility with < Navigate 2.1 themes (to be removed)
                $properties_names = array_keys($properties_assoc);
                $block = block::block_group_block_by_property($properties_names[0]);
            }
            if (!isset($block->properties) || empty($block->properties)) {
                return false;
            }
            $properties = $block->properties;
        } else {
            $properties = property::elements($template, $object_type);
        }
        if (!is_array($properties)) {
            $properties = array();
        }
        foreach ($properties as $property) {
            if (!isset($properties_assoc[$property->name]) && !isset($properties_assoc[$property->id])) {
                continue;
            }
            $values_dict = array();
            $value = '';
            // we try to find the property value by "property name", if empty then we try to find it via "property id"
            if (isset($properties_assoc[$property->name])) {
                $value = $properties_assoc[$property->name];
            }
            if (empty($value)) {
                $value = $properties_assoc[$property->id];
            }
            // multilanguage property?
            if (in_array($property->type, array('text', 'textarea', 'link', 'rich_textarea')) || @$property->multilanguage == 'true' || @$property->multilanguage === true) {
                if (isset($properties_assoc[$property->name])) {
                    $values_dict = $properties_assoc[$property->name];
                }
                if (empty($values_dict)) {
                    $values_dict = $properties_assoc[$property->id];
                }
                $value = '[dictionary]';
            }
            if ($property->type == 'coordinates') {
                if (is_array($value)) {
                    $value = $value['latitude'] . '#' . $value['longitude'];
                }
                // if it isn't an array, then we suppose it already has the right format
            }
            // property->type "decimal"; we don't need to reconvert, it should already be in the right format
            if ($property->type == 'webuser_groups' && !empty($value)) {
                $value = 'g' . implode(',g', $value);
            }
            // boolean (checkbox): if not checked,  form does not send the value
            if ($property->type == 'boolean' && empty($value)) {
                $value = 0;
            }
            if (is_null($value)) {
                $value = "";
            }
            // should not be needed because of value_or_default, but doing this here fixes some warnings
            // remove the old property value row
            $DB->execute('
				DELETE FROM nv_properties_items
                	  WHERE property_id = ' . protect($property->id) . '
                        AND element = ' . protect($property_object_type) . '
                        AND node_id = ' . protect($object_id) . (empty($node_uid) ? '' : ' AND node_uid = ' . protect($node_uid)) . '
                        AND website = ' . $ws->id);
            // now we insert a new row
            $DB->execute('
			    INSERT INTO nv_properties_items
				    (id, website, property_id, element, node_id, node_uid, name, value)
				VALUES
				    (   0,
						:website,
						:property_id,
						:type,
						:object_id,
						:node_uid,
						:name,
						:value
                    )', array(':website' => $ws->id, ':property_id' => $property->id, ':type' => $property_object_type, ':object_id' => value_or_default($object_id, 0), ':node_uid' => value_or_default($node_uid, ""), ':name' => $property->name, ':value' => value_or_default($value, "")));
            // $error = $DB->get_last_error();
            // set the dictionary for the multilanguage properties
            $default_language = '';
            if (isset($property->multilanguage) && ($property->multilanguage === 'false' || $property->multilanguage === false)) {
                $default_language = $ws->languages_list[0];
            }
            if (in_array($property->type, array('text', 'textarea', 'rich_textarea', 'link')) || @$property->multilanguage == 'true' || @$property->multilanguage === true) {
                foreach ($ws->languages_list as $lang) {
                    if (!empty($default_language)) {
                        // property is NOT multilanguage, use the first value for all languages
                        $dictionary[$lang]['property-' . $property->id . '-' . $lang] = $values_dict[$default_language];
                    } else {
                        $dictionary[$lang]['property-' . $property->id . '-' . $lang] = $values_dict[$lang];
                    }
                }
            }
        }
        if (!empty($dictionary)) {
            webdictionary::save_element_strings('property-' . $property_object_type, $object_id, $dictionary, $ws->id, $node_uid);
        }
        return true;
    }
Exemplo n.º 3
0
 public static function export_sample($a_categories, $a_items, $a_block_groups, $a_blocks, $a_comments, $folder)
 {
     global $website;
     global $theme;
     global $DB;
     @set_time_limit(0);
     $categories = array();
     $items = array();
     $blocks = array();
     $block_groups = array();
     $comments = array();
     $properties = array();
     $files = array();
     $settings = array();
     // structure
     for ($c = 0; $c < count($a_categories); $c++) {
         $tmp = new structure();
         $tmp->load($a_categories[$c]);
         //$properties['structure'][$tmp->id] = property::load_properties_associative('structure', $tmp->template, 'structure', $tmp->id);
         $properties['structure'][$tmp->id] = property::load_properties('structure', $tmp->template, 'structure', $tmp->id);
         $categories[$tmp->id] = $tmp;
         // add files referenced in properties
         if (is_array($properties['structure'][$tmp->id])) {
             foreach ($properties['structure'][$tmp->id] as $property) {
                 if ($property->type == 'image' || $property->type == 'file') {
                     $files[] = $property->value;
                 }
             }
         }
     }
     // comments
     for ($c = 0; $c < count($a_comments); $c++) {
         $tmp = new comment();
         $tmp->load($a_comments[$c]);
         $comments[$tmp->id] = $tmp;
     }
     // items
     for ($i = 0; $i < count($a_items); $i++) {
         $tmp = new item();
         $tmp->load($a_items[$i]);
         $template_id = $tmp->template;
         if ($tmp->association != "free" && $tmp->embedding == 1) {
             // we have to get the template set in the category of the item
             $template_id = $DB->query_single('template', 'nv_structure', ' id = ' . protect($tmp->category) . ' AND website = ' . $website->id);
         }
         $properties['item'][$tmp->id] = property::load_properties('item', $template_id, 'item', $tmp->id);
         list($tmp->dictionary, $files) = theme::export_sample_parse_dictionary($tmp->dictionary, $files);
         // add files referenced in properties
         if (is_array($properties['item'][$tmp->id])) {
             foreach ($properties['item'][$tmp->id] as $property) {
                 if ($property->type == 'image' || $property->type == 'file') {
                     $files[] = $property->value;
                 }
             }
         }
         // add files referenced in gallery
         if (is_array($tmp->galleries[0])) {
             $gallery_images = array_keys($tmp->galleries[0]);
             $files = array_merge($files, $gallery_images);
         }
         $items[$tmp->id] = $tmp;
     }
     // block_groups
     for ($i = 0; $i < count($a_block_groups); $i++) {
         $tmp = new block_group();
         $tmp->load($a_block_groups[$i]);
         $block_groups[$tmp->id] = $tmp;
         if (is_array($tmp->blocks)) {
             foreach ($tmp->blocks as $bgb) {
                 if ($bgb['type'] == 'block_group_block') {
                     $properties['block_group_block'][$a_block_groups[$i]][$bgb['uid']] = property::load_properties($bgb['id'], $tmp->code, 'block_group_block', $bgb['id'], $bgb['uid']);
                 } else {
                     if ($bgb['type'] == 'extension') {
                         $properties['block_group_block'][$a_block_groups[$i]][$bgb['uid']] = property::load_properties(NULL, $bgb['id'], "extension_block", NULL, $bgb['uid']);
                     }
                 }
             }
         }
         // note: maybe not all blocks in the group have been selected in the "blocks" tab
         // here we only export the block group definition, the block group blocks properties and the extension blocks properties, not adding anything else to export
     }
     // blocks
     for ($i = 0; $i < count($a_blocks); $i++) {
         $tmp = new block();
         $tmp->load($a_blocks[$i]);
         $properties['block'][$tmp->id] = property::load_properties('block', $tmp->type, 'block', $tmp->id);
         list($tmp->dictionary, $files) = theme::export_sample_parse_dictionary($tmp->dictionary, $files);
         list($tmp->trigger['trigger-content'], $files) = theme::export_sample_parse_array($tmp->trigger['trigger-content'], $files);
         list($tmp->trigger['trigger-html'], $files) = theme::export_sample_parse_array($tmp->trigger['trigger-html'], $files);
         if (!empty($tmp->trigger['trigger-image'])) {
             $files = array_merge($files, array_values($tmp->trigger['trigger-image']));
         }
         if (!empty($tmp->trigger['trigger-rollover'])) {
             $files = array_merge($files, array_values($tmp->trigger['trigger-rollover']));
         }
         if (!empty($tmp->trigger['trigger-rollover-active'])) {
             $files = array_merge($files, array_values($tmp->trigger['trigger-rollover-active']));
         }
         if (!empty($tmp->trigger['trigger-flash'])) {
             $files = array_merge($files, array_values($tmp->trigger['trigger-flash']));
         }
         if (!empty($tmp->action['action-image'])) {
             $files = array_merge($files, array_values($tmp->action['action-image']));
         }
         if (!empty($tmp->action['action-file'])) {
             $files = array_merge($files, array_values($tmp->action['action-file']));
         }
         // add files referenced in properties
         if (is_array($properties['block'][$tmp->id])) {
             foreach ($properties['block'][$tmp->id] as $property) {
                 if ($property->type == 'image' || $property->type == 'file') {
                     $files[] = $property->value;
                 }
             }
         }
         $blocks[$tmp->id] = $tmp;
     }
     // folders
     // save references and get their files list
     $folders = array();
     $folders_to_check = array();
     if (!empty($folder)) {
         array_push($folders_to_check, $folder);
         while (!empty($folders_to_check)) {
             $f = array_shift($folders_to_check);
             $f = file::filesOnPath($f);
             foreach ($f as $file) {
                 if ($file->type == 'folder') {
                     array_push($folders_to_check, $file->id);
                     array_push($folders, $file);
                 } else {
                     $files[] = $file->id;
                 }
             }
         }
     }
     // add files selected as theme_options
     foreach ($theme->options as $to) {
         if ($to->type == 'image' || $to->type == 'file') {
             $to_value = $website->theme_options->{$to->id};
             if (is_array($to_value)) {
                 $files = array_merge($files, $to_value);
             } else {
                 $files[] = $to_value;
             }
         }
     }
     // include favicon in file list
     if (!empty($website->favicon)) {
         $files[] = $website->favicon;
     }
     // files
     $files = array_unique($files);
     for ($f = 0; $f < count($files); $f++) {
         $file = new file();
         $file->load($files[$f]);
         $files[$f] = $file;
     }
     // settings
     $settings['homepage'] = $website->homepage;
     $settings['favicon'] = $website->favicon;
     $zip = new zipfile();
     $zip->addFile(var_export($website->languages, true), 'languages.var_export');
     $zip->addFile(var_export($website->theme_options, true), 'theme_options.var_export');
     $zip->addFile(var_export($categories, true), 'structure.var_export');
     $zip->addFile(var_export($items, true), 'items.var_export');
     $zip->addFile(var_export($block_groups, true), 'block_groups.var_export');
     $zip->addFile(var_export($blocks, true), 'blocks.var_export');
     $zip->addFile(var_export($comments, true), 'comments.var_export');
     $zip->addFile(var_export($files, true), 'files.var_export');
     $zip->addFile(var_export($folders, true), 'folders.var_export');
     $zip->addFile(var_export($properties, true), 'properties.var_export');
     $zip->addFile(var_export($settings, true), 'settings.var_export');
     foreach ($files as $file) {
         $zip->addFile(file_get_contents($file->absolute_path()), 'files/' . $file->id);
     }
     $contents = $zip->file();
     header('Content-Disposition: attachment; filename="' . $website->theme . '_sample.zip"');
     header("Content-type: application/octet-stream");
     header('Content-Length: ' . strlen($contents));
     echo $contents;
 }
Exemplo n.º 4
0
function run()
{
    global $layout;
    global $DB;
    global $website;
    $out = '';
    $item = new block();
    switch ($_REQUEST['act']) {
        case 'json':
        case 1:
            // json data retrieval & operations
            switch ($_REQUEST['oper']) {
                case 'del':
                    // remove rows
                    $ids = $_REQUEST['ids'];
                    foreach ($ids as $id) {
                        $item->load($id);
                        $item->delete();
                    }
                    echo json_encode(true);
                    break;
                default:
                    // list or search
                    // translation of request search & order fields
                    switch ($_REQUEST['searchField']) {
                        case 'id':
                            $_REQUEST['searchField'] = 'b.id';
                            break;
                        case 'type':
                            $_REQUEST['searchField'] = 'b.type';
                            break;
                        case 'title':
                            $_REQUEST['searchField'] = 'd.text';
                            break;
                        case 'category':
                            $_REQUEST['searchField'] = 'b.category';
                            break;
                        case 'dates':
                            $_REQUEST['searchField'] = 'b.date_published';
                            break;
                        case 'enabled':
                            $_REQUEST['searchField'] = 'b.enabled';
                            break;
                        case 'date_modified':
                        default:
                            $_REQUEST['searchField'] = 'b.date_modified';
                    }
                    if ($_REQUEST['sidx'] == 'dates') {
                        $_REQUEST['sidx'] = 'b.date_published';
                    }
                    $page = intval($_REQUEST['page']);
                    $max = intval($_REQUEST['rows']);
                    $offset = ($page - 1) * $max;
                    $orderby = $_REQUEST['sidx'] . ' ' . $_REQUEST['sord'];
                    $where = " 1=1 ";
                    if ($_REQUEST['_search'] == 'true' || isset($_REQUEST['quicksearch'])) {
                        if (isset($_REQUEST['quicksearch'])) {
                            $where .= $item->quicksearch($_REQUEST['quicksearch']);
                        } else {
                            if (isset($_REQUEST['filters'])) {
                                $where .= navitable::jqgridsearch($_REQUEST['filters']);
                                // special case
                                if (strpos($where, 'title LIKE') !== false) {
                                    $where = substr_replace($where, 'd.text', strpos($where, 'title LIKE'), 5);
                                }
                            } else {
                                // single search
                                $where .= ' AND ' . navitable::jqgridcompare($_REQUEST['searchField'], $_REQUEST['searchOper'], $_REQUEST['searchString']);
                            }
                        }
                    }
                    $sql = ' SELECT SQL_CALC_FOUND_ROWS b.*, d.text as title 
							   FROM nv_blocks b
						  LEFT JOIN nv_webdictionary d
						  		 	 ON b.id = d.node_id
								 	AND d.node_type = "block"
									AND d.subtype = "title"
									AND d.lang = "' . $website->languages_list[0] . '"
									AND d.website = ' . $website->id . '
							  WHERE ' . $where . '
							    AND b.website = ' . $website->id . ' 
						   ORDER BY ' . $orderby . ' 
							  LIMIT ' . $max . '
							 OFFSET ' . $offset;
                    if (!$DB->query($sql, 'array')) {
                        throw new Exception($DB->get_last_error());
                    }
                    $dataset = $DB->result();
                    $total = $DB->foundRows();
                    $block_types = block::types();
                    $block_types_list = array();
                    for ($i = 0; $i < count($block_types); $i++) {
                        if (is_numeric($block_types[$i]['id'])) {
                            $block_types_list[$block_types[$i]['code']] = $block_types[$i]['title'];
                        } else {
                            $block_types_list[$block_types[$i]['id']] = $block_types[$i]['title'];
                        }
                    }
                    $dataset = grid_notes::summary($dataset, 'block', 'id');
                    // we need to format the values and retrieve the needed strings from the dictionary
                    $out = array();
                    for ($i = 0; $i < count($dataset); $i++) {
                        if (empty($dataset[$i])) {
                            continue;
                        }
                        $access = array(0 => '<img src="img/icons/silk/page_white_go.png" align="absmiddle" title="' . t(254, 'Everybody') . '" />', 1 => '<img src="img/icons/silk/lock.png" align="absmiddle" title="' . t(361, 'Web users only') . '" />', 2 => '<img src="img/icons/silk/user_gray.png" align="absmiddle" title="' . t(363, 'Users who have not yet signed up or signed in') . '" />', 3 => '<img src="img/icons/silk/group_key.png" align="absmiddle" title="' . t(512, "Selected web user groups") . '" />');
                        if (empty($dataset[$i]['date_published'])) {
                            $dataset[$i]['date_published'] = '&infin;';
                        } else {
                            $dataset[$i]['date_published'] = core_ts2date($dataset[$i]['date_published'], false);
                        }
                        if (empty($dataset[$i]['date_unpublish'])) {
                            $dataset[$i]['date_unpublish'] = '&infin;';
                        } else {
                            $dataset[$i]['date_unpublish'] = core_ts2date($dataset[$i]['date_unpublish'], false);
                        }
                        if ($dataset[$i]['category'] > 0) {
                            $dataset[$i]['category'] = $DB->query_single('text', 'nv_webdictionary', ' 	node_type = "structure" AND
                                    node_id = "' . $dataset[$i]['category'] . '" AND
                                    subtype = "title" AND
                                    lang = "' . $website->languages_list[0] . '"
                                ');
                        }
                        $out[$i] = array(0 => $dataset[$i]['id'], 1 => $block_types_list[$dataset[$i]['type']], 2 => '<div class="list-row" data-enabled="' . $dataset[$i]['enabled'] . '">' . $dataset[$i]['title'] . '</div>', 3 => $dataset[$i]['date_published'] . ' - ' . $dataset[$i]['date_unpublish'], 4 => $access[$dataset[$i]['access']], 5 => $dataset[$i]['enabled'] == 1 ? '<img src="img/icons/silk/accept.png" />' : '<img src="img/icons/silk/cancel.png" />', 6 => $dataset[$i]['_grid_notes_html']);
                    }
                    navitable::jqgridJson($out, $page, $offset, $max, $total);
                    break;
            }
            session_write_close();
            exit;
            break;
        case 'load':
        case 'edit':
        case 2:
            // edit/new form
            if (!empty($_REQUEST['id'])) {
                $item->load(intval($_REQUEST['id']));
            }
            if (isset($_REQUEST['form-sent'])) {
                $item->load_from_post();
                try {
                    $item->save();
                    property::save_properties_from_post('block', $item->id);
                    $id = $item->id;
                    // set block order
                    if (!empty($item->type) && !empty($_REQUEST['blocks-order'])) {
                        block::reorder($item->type, $_REQUEST['blocks-order'], $_REQUEST['blocks-order-fixed']);
                    }
                    unset($item);
                    $item = new block();
                    $item->load($id);
                    $layout->navigate_notification(t(53, "Data saved successfully."), false, false, 'fa fa-check');
                } catch (Exception $e) {
                    $layout->navigate_notification($e->getMessage(), true, true);
                }
                users_log::action($_REQUEST['fid'], $item->id, 'save', $item->dictionary[$website->languages_list[0]]['title'], json_encode($_REQUEST));
            } else {
                users_log::action($_REQUEST['fid'], $item->id, 'load', $item->dictionary[$website->languages_list[0]]['title']);
            }
            $out = blocks_form($item);
            break;
        case 'delete':
        case 4:
            // remove
            if (!empty($_REQUEST['id'])) {
                $item->load(intval($_REQUEST['id']));
                if ($item->delete() > 0) {
                    $layout->navigate_notification(t(55, 'Item removed successfully.'), false);
                    $out = blocks_list();
                } else {
                    $layout->navigate_notification(t(56, 'Unexpected error.'), false);
                    $out = blocks_form($item);
                }
                users_log::action($_REQUEST['fid'], $item->id, 'remove', $item->dictionary[$website->languages_list[0]]['title']);
            }
            break;
        case 'path':
        case 5:
            // search an existing path
            $DB->query('SELECT path as id, path as label, path as value
						  FROM nv_paths
						 WHERE path LIKE ' . protect('%' . $_REQUEST['term'] . '%') . ' 
						   AND website = ' . $website->id . '
				      ORDER BY path ASC
					     LIMIT 10', 'array');
            echo json_encode($DB->result());
            core_terminate();
            break;
        case 'block_groups_list':
            $out = block_groups_list();
            break;
        case 'block_groups_json':
            // block groups: json data retrieval
            $page = intval($_REQUEST['page']);
            $max = intval($_REQUEST['rows']);
            $offset = ($page - 1) * $max;
            list($rs, $total) = block_group::paginated_list($offset, $max, $_REQUEST['sidx'], $_REQUEST['sord']);
            $rs = grid_notes::summary($rs, 'block_group', 'id');
            // translate $rs to an array of ordered fields
            foreach ($rs as $row) {
                if (substr($row['blocks'], 0, 2) == 'a:') {
                    // nv < 2.1
                    $row['blocks'] = mb_unserialize($row['blocks']);
                } else {
                    // nv >= 2.1
                    $row['blocks'] = json_decode($row['blocks'], true);
                }
                $dataset[] = array('id' => $row['id'], 'code' => $row['code'], 'title' => $row['title'], 'blocks' => count($row['blocks']), 'notes' => $row['_grid_notes_html']);
            }
            navitable::jqgridJson($dataset, $page, $offset, $max, $total, 'id');
            session_write_close();
            exit;
            break;
        case 'block_group_edit':
            $item = new block_group();
            if (!empty($_REQUEST['id'])) {
                $item->load(intval($_REQUEST['id']));
            }
            if (isset($_REQUEST['form-sent'])) {
                $item->load_from_post();
                try {
                    $item->save();
                    $layout->navigate_notification(t(53, "Data saved successfully."), false, false, 'fa fa-check');
                } catch (Exception $e) {
                    $layout->navigate_notification($e->getMessage(), true, true);
                }
                users_log::action($_REQUEST['fid'], $item->id, 'save', $item->title, json_encode($_REQUEST));
            } else {
                if (!empty($_REQUEST['id'])) {
                    users_log::action($_REQUEST['fid'], $item->id, 'edit', $item->title);
                }
            }
            $out = block_group_form($item);
            break;
        case 'block_group_delete':
            $item = new block_group();
            if (!empty($_REQUEST['id'])) {
                $item->load(intval($_REQUEST['id']));
                if ($item->delete() > 0) {
                    $layout->navigate_notification(t(55, 'Item removed successfully.'), false);
                    $out = block_groups_list();
                } else {
                    $layout->navigate_notification(t(56, 'Unexpected error.'), false);
                    $out = block_group_form($item);
                }
                users_log::action($_REQUEST['fid'], $item->id, 'remove', $item->title);
            }
            break;
        case 'block_types_list':
            $out = blocks_types_list();
            break;
        case 'block_types_json':
            // block types: json data retrieval
            $page = intval($_REQUEST['page']);
            $max = intval($_REQUEST['rows']);
            $offset = ($page - 1) * $max;
            $rs = block::types($_REQUEST['sidx'], $_REQUEST['sord']);
            $block_modes = block::modes();
            // translate $rs to an array of ordered fields
            foreach ($rs as $row) {
                $dataset[] = array('id' => $row['id'], 'type' => $block_modes[$row['type']], 'code' => $row['code'], 'title' => $row['title'], 'width' => $row['width'], 'height' => $row['height']);
            }
            $total = count($dataset);
            navitable::jqgridJson($dataset, $page, $offset, $max, $total, 'id');
            session_write_close();
            exit;
            break;
        case 'block_type_edit':
        case 82:
            // edit/create block type
            $item = NULL;
            $position = NULL;
            $max_id = 0;
            $dataset = block::custom_types();
            for ($i = 0; $i < count($dataset); $i++) {
                if ($dataset[$i]['id'] > $max_id) {
                    $max_id = $dataset[$i]['id'];
                }
                if ($dataset[$i]['id'] == $_REQUEST['id']) {
                    $item = $dataset[$i];
                    $position = $i;
                }
            }
            if (empty($item)) {
                $layout->navigate_notification(t(599, "Sorry, can't display a theme block type info."));
                $out = blocks_types_list();
            } else {
                if (isset($_REQUEST['form-sent'])) {
                    if (empty($item)) {
                        $item = array('id' => $max_id + 1);
                    }
                    $item['type'] = $_REQUEST['type'];
                    $item['title'] = $_REQUEST['title'];
                    $item['code'] = $_REQUEST['code'];
                    $item['width'] = $_REQUEST['width'];
                    $item['height'] = $_REQUEST['height'];
                    $item['order'] = $_REQUEST['order'];
                    $item['maximum'] = $_REQUEST['maximum'];
                    $item['notes'] = pquotes($_REQUEST['notes']);
                    if (!is_null($position)) {
                        $dataset[$position] = $item;
                    } else {
                        $dataset[] = $item;
                    }
                    try {
                        // save
                        $ok = block::types_update($dataset);
                        $layout->navigate_notification(t(53, "Data saved successfully."), false, false, 'fa fa-check');
                    } catch (Exception $e) {
                        $layout->navigate_notification($e->getMessage(), true, true);
                    }
                }
                $out = blocks_type_form($item);
            }
            break;
        case 'block_type_delete':
        case 84:
            // remove block type
            $dataset = block::custom_types();
            $item = NULL;
            for ($i = 0; $i < count($dataset); $i++) {
                if ($dataset[$i]['id'] == $_REQUEST['id']) {
                    unset($dataset[$i]);
                    break;
                }
            }
            try {
                block::types_update($dataset);
                $layout->navigate_notification(t(55, 'Item removed successfully.'), false);
                $out = blocks_types_list();
            } catch (Exception $e) {
                $out = $layout->navigate_message("error", t(23, 'Blocks'), t(56, 'Unexpected error.'));
            }
            break;
        case 'block_property_load':
            $property = new property();
            if (!empty($_REQUEST['id'])) {
                if (is_numeric($_REQUEST['id'])) {
                    $property->load(intval($_REQUEST['id']));
                } else {
                    $property->load_from_theme($_REQUEST['id'], null, 'block', $_REQUEST['block']);
                }
            }
            header('Content-type: text/json');
            $types = property::types();
            $property->type_text = $types[$property->type];
            echo json_encode($property);
            session_write_close();
            exit;
            break;
        case 'block_property_save':
            // save property details
            $property = new property();
            if (!empty($_REQUEST['property-id'])) {
                $property->load(intval($_REQUEST['property-id']));
            }
            $property->load_from_post();
            $property->save();
            header('Content-type: text/json');
            $types = property::types();
            $property->type_text = $types[$property->type];
            echo json_encode($property);
            session_write_close();
            exit;
            break;
        case 'block_property_remove':
            // remove property
            $property = new property();
            if (!empty($_REQUEST['property-id'])) {
                $property->load(intval($_REQUEST['property-id']));
            }
            $property->delete();
            session_write_close();
            exit;
            break;
        case 'block_group_block_options':
            $status = null;
            $block_group = $_REQUEST['block_group'];
            $block_code = $_REQUEST['code'];
            $block_uid = $_REQUEST['block_uid'];
            if (isset($_REQUEST['form-sent'])) {
                $status = property::save_properties_from_post('block_group_block', $block_code, $block_group, $block_code, $block_uid);
            }
            $out = block_group_block_options($block_group, $block_code, $block_uid, $status);
            echo $out;
            core_terminate();
            break;
        case 'block_group_extension_block_options':
            $status = null;
            $block_group = $_REQUEST['block_group'];
            // block_group type
            $block_id = $_REQUEST['block_id'];
            // extension block id (type)
            $block_uid = $_REQUEST['block_uid'];
            // extension block unique id
            $block_extension = $_REQUEST['block_extension'];
            // extension name
            if (isset($_REQUEST['form-sent'])) {
                $status = property::save_properties_from_post('extension_block', $block_group, $block_id, null, $block_uid);
            }
            $out = block_group_extension_block_options($block_group, $block_extension, $block_id, $block_uid, $status);
            echo $out;
            core_terminate();
            break;
        case 0:
            // list / search result
        // list / search result
        default:
            $out = blocks_list();
            break;
    }
    return $out;
}