pepiscms/modules/crud/libraries/AdminCRUDController.php
<?php
/**
* PepisCMS
*
* Simple content management system
*
* @package PepisCMS
* @author Piotr Polak
* @copyright Copyright (c) 2007-2018, Piotr Polak
* @license See LICENSE.txt
* @link http://www.polak.ro/
*/
defined('BASEPATH') or exit('No direct script access allowed');
/**
* Controller class for building admin CRUD Controllers with no effort
* The controller supposes every CRUD consist of index (display), edit (Create/Update), preview and delete actions.
*
* You can overwrite module views by creating respective files inside your module
*
* @since 0.2.0
*/
abstract class AdminCRUDController extends ModuleAdminController
{
/**
* Database table name used for Generic_model when no feed object is specified
*
* @var string
*/
private $table = '';
/**
* Where conditions to be applied for CRUD read
*
* @var bool|array
*/
private $where = false;
/**
* CRUD definition used for FormBuilder and DataGrid
*
* @var bool|array
*/
private $definition = false;
/**
* CRUD template files path
*
* @var string
*/
private $template_path = '';
/**
* Current module template files path
*
* @var string
*/
private $current_module_template_path = '';
/**
* Name of the column used for ordering
*
* @var string
*/
private $item_order_column = 'item_order';
/**
* Name of the column used for constraining the order - the order action is applied only among rows having the same
* constraining column value
*
* @var bool|string
*/
private $item_order_constraint_column = false;
/**
* Name of the column used for stating
*
* @var string
*/
private $is_stared_column = 'is_stared';
/**
* Variable used for overwriting star action label
*
* @var bool|string
*/
private $is_stared_label = false;
/**
* Variable indicating whether the CRUD is orderable
*
* @var bool
*/
private $is_orderable = false;
/**
* Variable indicating whether the CRUD is starable
*
* @var bool
*/
private $is_starable = false;
/**
* Variable indicating whether the CRUD is addable
*
* @var bool
*/
private $is_addable = true;
/**
* Variable indicating whether the CRUD is editable
*
* @var bool
*/
private $is_editable = true;
/**
* Variable indicating whether the CRUD is deletable
*
* @var bool
*/
private $is_deletable = true;
/**
* Variable indicating whether the CRUD is previewable
*
* @var bool
*/
private $is_previewable = true;
/**
* Variable indicating whether the CRUD is importable
*
* @var bool
*/
private $is_importable = false;
/**
* Array containing list of fields that must be specified for the the entry to be imported
*
* @var bool|array
*/
private $is_importable_must_have_fields = false;
/**
* Data filtering callback
*
* @var bool|callback
*/
private $is_importable_data_formatting_callback = false;
/**
* Variable indicating whether the CRUD data is exportable
*
* @var bool
*/
private $is_exportable = false;
/**
* @var bool
*/
private $is_exportable_data_formatting_callback = false;
/**
* When set to false, the edit action is still accessible but not displayed in DataGrid
*
* @var bool
*/
private $is_edit_action_displayed_in_grid = true;
/**
* Feed object used by both DataGrid and FormBuilder
*
* @var bool|Generic_model
*/
private $feed_object = false;
/**
* Whether the popup action is enabled
*
* @var bool
*/
private $is_popup_enabled = true;
/**
* Image field name
*
* @var bool|string
*/
private $meta_image_field = false;
/**
* Base URL for displaying meta images
* @var bool|string
*/
private $meta_image_base_url = false;
/**
* Pattern used by meta title
*
* @var bool|string
*/
private $meta_title_pattern = false;
/**
* Some kind of cache
*
* @var bool|array
*/
private $meta_title_pattern_keys = false;
/**
* Pattern used by meta description
*
* @var bool|string
*/
private $meta_description_pattern = false;
/**
* Callback used by meta description
*
* @var bool|callback
*/
private $meta_description_pattern_callback = false;
/**
* Some kind of cache
*
* @var bool|array
*/
private $meta_description_pattern_keys = false;
/**
* Label displayed in meta order column
*
* @var bool|string
*/
private $meta_order_field_label = false;
/**
* Meta order field
*
* @var string
*/
private $meta_order_field = 'id';
/**
* ID field name used for CRUD operations
*
* @var string
*/
private $id_field_name = 'id';
/**
* Variable used for overwriting add new item label
*
* @var bool|string
*/
private $add_new_item_label = false;
/**
* Variable used for overwriting back to items label
*
* @var bool|string
*/
private $back_to_items_label = false;
/**
* DataGrid meta actions
*
* @var array
*/
private $datagrid_meta_actions = array();
/**
* Parameter that is passed to DataGrid generate method
* @var bool|mixed
*/
private $datagrid_generate_parameter = false;
/**
* Tooltip text for index, false if hidden
*
* @var bool|string
*/
private $tooltip_text_for_index = false;
/**
* Tooltip text for edit, false if hidden
*
* @var bool|string
*/
private $tooltip_text_for_edit = false;
/**
* Array containing the list of actions to be rendered on index page
*
* @var array
*/
private $actions_for_index = array();
/**
* Array containing the list of actions to be rendered on edit page
*
* @var array
*/
private $actions_for_edit = array();
/**
* URL used as a back link on index page
*
* @var bool|string
*/
private $back_action_for_index = false;
/**
* HTML Meta title
*
* @var string
*/
private $title = '';
/**
* Array containing the list of forced filters
*
* @var bool|array
*/
private $_forced_filters = false;
/**
* URL used as a back link on edit pages
*
* @var bool|string
*/
private $back_link_for_edit = false;
/**
* Base module URL for index
*
* @var bool|string
*/
private $base_module_url = false;
/**
* Default constructor
*/
public function __construct()
{
parent::__construct();
$this->assign('running_module', $this->modulerunner->getRunningModuleName());
$this->base_module_url = module_url();
$this->load->library(array('DataGrid', 'FormBuilder'));
$this->load->moduleLanguage('crud', 'crud');
$this->template_path = module_path('crud') . '/views/admin/';
$this->current_module_template_path = module_path() . '/views/admin/';
$this->assign('bredcrumb_steps_assoc_array', '');
}
/**
* Returns name of the current module
*
* @since 0.2.4.1
* @return string
*/
protected function getModuleName()
{
return strtolower(str_replace('Admin', '', get_class($this)));
}
/**
* Returns name of the current module's model
*
* @since 0.2.4.1
* @return string
*/
protected function getModelName()
{
$model_name = ucfirst($this->getModuleName());
if (substr($model_name, strlen($model_name) - 3) == 'ies') {
$model_name = substr($model_name, 0, strlen($model_name) - 3) . 'y';
} elseif (substr($model_name, strlen($model_name) - 2) == 'es') {
$model_name = substr($model_name, 0, strlen($model_name) - 2);
} elseif ($model_name[strlen($model_name) - 1] == 's') {
$model_name = substr($model_name, 0, strlen($model_name) - 1);
}
$model_name .= '_model';
return $model_name;
}
/**
* Returns template path
*
* @return string
*/
protected function getTemplatePath()
{
return $this->template_path;
}
/**
* Sets explanation message
* @param String $tooltip_text
* @return AdminCRUDController
*/
protected function setTooltipTextForIndex($tooltip_text)
{
$this->tooltip_text_for_index = $tooltip_text;
return $this;
}
/**
* Sets explanation message
* @param string $tooltip_text
* @return AdminCRUDController
*/
protected function setTooltipTextForEdit($tooltip_text)
{
$this->tooltip_text_for_edit = $tooltip_text;
return $this;
}
/**
* Adds an action that will be displayed in index using display_action_bar function
* Allowed keys: title, name, icon, link
*
* @param Array $action
* @return AdminCRUDController
*/
protected function addActionForIndex($action)
{
$this->actions_for_index[] = $action;
return $this;
}
/**
* Sets back action for index, to be used when the module is a subiew
* Allowed keys: title, name, icon, link
*
* @param Array $action
* @return AdminCRUDController
*/
protected function setBackActionForIndex($action)
{
if (!isset($action['icon'])) {
$action['icon'] = 'pepiscms/theme/img/dialog/actions/back_16.png';
}
$this->back_action_for_index = $action;
return $this;
}
/**
* Adds an action that will be displayed in index using display_action_bar function
* Allowed keys: title, name, icon, link
*
* @param Array $action
* @return AdminCRUDController
*/
protected function addActionForEdit($action)
{
$this->actions_for_edit[] = $action;
return $this;
}
/**
* Sets back URL for edit action
*
* There are situations when it is not desired to redirect the user to index
* You can use this method to change the default behavior
*
* @param String $back_link_for_edit
* @return AdminCRUDController
*/
protected function setBackLinkForEdit($back_link_for_edit)
{
$this->back_link_for_edit = $back_link_for_edit;
return $this;
}
/**
* Returns back URL for edit action
*
* @return String
*/
protected function getBackLinkForEdit()
{
if (!$this->back_link_for_edit) {
return $this->getModuleBaseUrl() . 'index' . $this->getCommonPathParamsString();
}
return $this->back_link_for_edit;
}
/**
* Returns base module URL for links
*
* @return string
*/
protected function getModuleBaseUrl()
{
return $this->base_module_url;
}
/**
* Sets base module URL for links
*
* @param $base_module_url
* @return AdminCRUDController
*/
protected function setModuleBaseUrl($base_module_url)
{
$this->base_module_url = $base_module_url;
return $this;
}
/**
* Sets breadcrumbs steps, associative array URL => LABEL
*
* @param Array $bredcrumb_steps_assoc_array
* @return AdminCRUDController
*/
protected function setBreadcrumbPathSteps($bredcrumb_steps_assoc_array)
{
$this->assign('bredcrumb_steps_assoc_array', $bredcrumb_steps_assoc_array);
return $this;
}
/**
* Set fields definition compatible with FormBuilder and DataGrid
*
* @param Array $definition
* @return AdminCRUDController
*/
protected function setDefinition($definition)
{
$this->definition = $definition;
return $this;
}
/**
* Removes filter by field name
*
* @param String $field
* @return AdminCRUDController
*/
protected function removeFilterByFieldName($field)
{
if (isset($this->definition[$field]['filter_type'])) {
$this->definition[$field]['filter_type'] = false;
}
return $this;
}
/**
* Returns CRUD definition
*
* @return Array
*/
protected function getDefinition()
{
if (!$this->definition) {
$definition = array();
$fields = $this->db->list_fields($this->getTable());
foreach ($fields as $field) {
$definition[] = array('field' => $field);
}
return $definition;
}
return $this->definition;
}
/**
* When set to true, the user can change order of elements.
* $item_order_column contains the name of collum containing order number.
* By default $item_order_column is set to item_order.
*
* @param bool $is_orderable
* @param bool|string $item_order_column
* @param bool|string $item_order_constraint_column
* @return $this
*/
protected function setOrderable($is_orderable = true, $item_order_column = false, $item_order_constraint_column = false)
{
if ($item_order_column !== false) {
$this->item_order_column = $item_order_column;
}
if ($item_order_constraint_column !== false) {
$this->item_order_constraint_column = $item_order_constraint_column;
}
$this->is_orderable = $is_orderable;
if ($this->is_orderable) {
$this->datagrid->setDefaultOrder($this->item_order_column);
} else {
$this->datagrid->setDefaultOrder(false);
}
return $this;
}
/**
* Makes the rows starable. You can use it to promote some items
*
* @param bool $is_starable
* @param bool|string $is_stared_column
* @param bool|string $is_stared_label
* @return $this
*/
protected function setStarable($is_starable = true, $is_stared_column = false, $is_stared_label = false)
{
if ($is_stared_column !== false) {
$this->is_stared_column = $is_stared_column;
}
$this->is_stared_label = $is_stared_label;
$this->is_starable = $is_starable;
return $this;
}
/**
* Tells whether the form is starable
*
* @return bool
*/
protected function isStarable()
{
return $this->is_starable;
}
/**
* Makes the CRUD importable
*
* @param bool $is_importable
* @param bool $must_have_fields
* @param bool $data_formatting_callback
* @return $this
*/
protected function setImportable($is_importable = true, $must_have_fields = false, $data_formatting_callback = false)
{
$this->is_importable = $is_importable;
$this->is_importable_must_have_fields = $must_have_fields;
$this->is_importable_data_formatting_callback = $data_formatting_callback;
return $this;
}
/**
* Tells whether the import action is enabled
*
* @return bool
*/
protected function isImportable()
{
return $this->is_importable;
}
/**
* Enables or disables export action
*
* @param bool $is_exportable
* @param bool $data_formatting_callback
* @return $this
*/
protected function setExportable($is_exportable = true, $data_formatting_callback = false)
{
$this->is_exportable = $is_exportable;
$this->is_exportable_data_formatting_callback = $data_formatting_callback;
return $this;
}
/**
* Tells whether export action is enabled
*
* @return bool
*/
protected function isExportable()
{
return $this->is_exportable;
}
/**
* Tells whether the form is orderable
*
* @return bool
*/
protected function isOrderable()
{
return $this->is_orderable;
}
/**
* Enables or disables edit action
*
* @param boolean $is_editable
* @return AdminCRUDController
*/
protected function setEditable($is_editable = true)
{
$this->is_editable = $is_editable;
return $this;
}
/**
* Tells whether edit action is enabled
*
* @return bool
*/
protected function isEditable()
{
return $this->is_editable;
}
/**
* You can hide edit action in the main grid while the edit action is still enabled
*
* @param boolean $is_edit_action_displayed_in_grid
* @return AdminCRUDController
*/
protected function setEditActionDisplayedInGrid($is_edit_action_displayed_in_grid = true)
{
$this->is_edit_action_displayed_in_grid = $is_edit_action_displayed_in_grid;
return $this;
}
/**
* Tells whether edit action is displayed in grid
*
* @return bool
*/
protected function isEditActionDisplayedInGrid()
{
return $this->is_edit_action_displayed_in_grid;
}
/**
* Enables or disables add action
*
* @param boolean $is_addable
* @return AdminCRUDController
*/
protected function setAddable($is_addable = true)
{
$this->is_addable = $is_addable;
return $this;
}
/**
* Tells whether the controller allows adding an element
*
* @return bool
*/
protected function isAddable()
{
return $this->is_addable;
}
/**
* Enables or disables delete action
*
* @param boolean $is_deletable
* @return AdminCRUDController
*/
protected function setDeletable($is_deletable = true)
{
$this->is_deletable = $is_deletable;
return $this;
}
/**
* Tells whether the controller allows deleting an element
*
* @return bool
*/
protected function isDeletable()
{
return $this->is_deletable;
}
/**
* Enables preview action
*
* @param boolean $is_previewable
* @return AdminCRUDController
*/
protected function setPreviewable($is_previewable = true)
{
$this->is_previewable = $is_previewable;
return $this;
}
/**
* Tells whether the controller allows element preview
*
* @return bool
*/
protected function isPreviewable()
{
return $this->is_previewable;
}
/**
* Sets parameter to datagrid->generate( $parameter) function
*
* @param boolean $parameter
* @return AdminCRUDController
*/
protected function setDataGridGenerateParameter($parameter = false)
{
$this->datagrid_generate_parameter = $parameter;
return $this;
}
/**
* Enables or disables popup
*
* @param boolean $is_popup_enabled
* @return AdminCRUDController
*/
protected function setPopupEnabled($is_popup_enabled = true)
{
$this->is_popup_enabled = $is_popup_enabled;
return $this;
}
/**
* Tells whether the popup is enabled
*
* @return bool
*/
protected function isPopupEnabled()
{
return $this->is_popup_enabled;
}
/**
* Tells whether the current layout is a popup
*
* @return bool
*/
protected function isLayoutPopup()
{
return $this->input->getParam('layout') == 'popup';
}
/**
* Returns name of item order column
*
* @return String
*/
protected function getItemOrderColumn()
{
return $this->item_order_column;
}
/**
* Returns name of column used as a constraint for item order
*
* @return String
*/
protected function getItemOrderConstraintColumn()
{
return $this->item_order_constraint_column;
}
/**
* Sets table from which data will be pulled
*
* @param string $table
* @return AdminCRUDController
*/
protected function setTable($table)
{
$this->table = $table;
$this->feed_object = false;
return $this;
}
/**
* Returns database table name used
*
* @return string
*/
protected function getTable()
{
return $this->getFeedObject() ? $this->getFeedObject()->getTable() : $this->table;
}
/**
* Sets ID field name
*
* @param string $id_field_name
* @return AdminCRUDController
*/
protected function setIdFieldName($id_field_name)
{
$this->id_field_name = $id_field_name;
return $this;
}
/**
* Returns ID field name
*
* @return string
*/
protected function getIdFieldName()
{
return $this->getFeedObject() ? $this->getFeedObject()->getIdFieldName() : $this->id_field_name;
}
/**
* Sets feed object
*
* @param $feed_object
* @return AdminCRUDController
*/
protected function setFeedObject($feed_object)
{
$this->feed_object = $feed_object;
$this->table = false;
$this->id_field_name = false;
return $this;
}
/**
* Returns feed object
*
* @return Generic_model
*/
protected function getFeedObject()
{
return $this->feed_object;
}
/**
* Set where conditions as associative array
*
* @param array $where
* @return AdminCRUDController
*/
protected function setWhere($where)
{
$this->where = $where;
return $this;
}
/**
* Returns associative array representing SQL where conditions
*
* @return array
*/
protected function getWhere()
{
return $this->where;
}
/**
* Sets page title
*
* @param string $title
* @return AdminCRUDController
*/
protected function setPageTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Returns page title
*
* @return string
*/
protected function getPageTitle()
{
return $this->title;
}
/**
* Sets add new item label
*
* @param string $add_new_item_label
* @return AdminCRUDController
*/
protected function setAddNewItemLabel($add_new_item_label)
{
$this->add_new_item_label = $add_new_item_label;
return $this;
}
/**
* Sets add new item label
*
* return string
*/
protected function getAddNewItemLabel()
{
if ($this->add_new_item_label) {
return $this->add_new_item_label;
}
return $this->lang->line('crud_label_add_item');
}
/**
* Sets back to items label
*
* @param string $back_to_items_label
* @return AdminCRUDController
*/
protected function setBackToItemsLabel($back_to_items_label)
{
$this->back_to_items_label = $back_to_items_label;
return $this;
}
/**
* Returns back to items label
*
* return string
*/
protected function getBackToItemsLabel()
{
if ($this->back_to_items_label) {
return $this->back_to_items_label;
}
return $this->lang->line('crud_label_back_to_items');
}
// *************************************************************************
// META
// *************************************************************************
/**
* Sets the field name and label for the meta column ordering
*
* @param $meta_order_field
* @param bool $meta_order_field_label
* @return $this
*/
protected function setMetaOrderField($meta_order_field, $meta_order_field_label = false)
{
$this->meta_order_field = $meta_order_field;
$this->meta_order_field_label = $meta_order_field_label;
return $this;
}
/**
* Gets the field name and label for the meta column ordering
*
* @return array(meta_order_field,meta_order_field_label)
*/
protected function getMetaOrderField()
{
return array(
'meta_order_field' => $this->meta_order_field,
'meta_order_field_label' => $this->meta_order_field_label,
);
}
/**
* Sets meta image field name and base url that will be prepended
*
* @param String $image_field
* @param String $image_base_url
* @return AdminCRUDController
*/
protected function setMetaImageField($image_field, $image_base_url = '')
{
$this->meta_image_field = $image_field;
$this->meta_image_base_url = $image_base_url;
return $this;
}
/**
* Sets title pattern
*
* Pattern is a text that contains references to row (line) variables
* @example "User {name} is {age} years old
*
* @param String $title_pattern
* @return AdminCRUDController
*/
protected function setMetaTitlePattern($title_pattern)
{
if (!is_callable($title_pattern)) {
$matches = array();
preg_match_all('/{([a-z_0-9]+)}/', $title_pattern, $matches);
$this->meta_title_pattern_keys = $matches[1];
}
$this->meta_title_pattern = $title_pattern;
return $this;
}
/**
* Returns meta title pattern
*
* @return String
*/
protected function getMetaTitlePattern()
{
return $this->meta_title_pattern;
}
/**
* Sets meta description pattern
*
* Pattern is a text that contains references to row (line) variables
* @example "User {name} is {age} years old
*
* @param String $description_pattern
* @param Callback $description_pattern_callback
* @return AdminCRUDController
*/
protected function setMetaDescriptionPattern($description_pattern, $description_pattern_callback = null)
{
if (!is_callable($description_pattern)) {
$matches = array();
preg_match_all('/{([a-z_0-9]+)}/', $description_pattern, $matches);
$this->meta_description_pattern_keys = $matches[1];
if (is_callable($description_pattern_callback)) {
$this->setMetaDescriptionPatternCallback($description_pattern_callback);
}
$this->meta_description_pattern = $description_pattern;
} else {
// $description_pattern callable
$this->setMetaDescriptionPatternCallback($description_pattern);
}
return $this;
}
/**
* Returns meta description pattern
*
* @return String
*/
protected function getMetaDescriptionPattern()
{
return $this->meta_description_pattern;
}
/**
* Sets meta description pattern callback
*
* @param Callback $description_pattern_callback
* @return AdminCRUDController
*/
protected function setMetaDescriptionPatternCallback($description_pattern_callback)
{
$this->meta_description_pattern_callback = $description_pattern_callback;
return $this;
}
/**
* Returns meta description pattern
*
* @return bool|callable
*/
protected function getMetaDescriptionPatternCallback()
{
return $this->meta_description_pattern_callback;
}
/**
* Adds a new meta action by link and label patterns
*
* Pattern is a text that contains references to row (line) variables
* @example "User {name} is {age} years old
*
* @param $link_pattern
* @param $label_pattern
* @param bool $css_class
* @param null $is_popup
* @param bool $target
* @return $this
*/
protected function addMetaAction($link_pattern, $label_pattern, $css_class = false, $is_popup = null, $target = false)
{
if (!is_callable($link_pattern)) {
preg_match_all('/{([a-z_0-9]+)}/', $link_pattern, $matches_link);
} else {
$matches_link[1] = $link_pattern;
}
preg_match_all('/{([a-z_0-9]+)}/', $label_pattern, $matches_label);
if ($is_popup === null) {
$is_popup = $this->isPopupEnabled();
}
$this->datagrid_meta_actions[] = array(
'link_pattern' => $link_pattern,
'link_pattern_keys' => $matches_link[1],
'label_pattern' => $label_pattern,
'label_pattern_keys' => $matches_label[1],
'css_class' => $css_class,
'is_popup' => $is_popup,
'target' => $target
);
return $this;
}
/**
* Removes all options from meta actions
* use on your own risk!
*
* @return AdminCRUDController
*/
protected function removeMetaActions()
{
$this->datagrid_meta_actions = array();
return $this;
}
/**
* Removes all options from actions for index
* use on your own risk!
*
* @return AdminCRUDController
*/
protected function removeActionsForIndex()
{
$this->actions_for_index = array();
return $this;
}
/**
* Removes all options from actions for edit
* use on your own risk!
*
* @return AdminCRUDController
*/
protected function removeActionsForEdit()
{
$this->actions_for_edit = array();
return $this;
}
/**
* Returns the list of forced filers
*
* @return array
*/
protected function getForcedFilters()
{
if (!$this->_forced_filters) {
$this->_forced_filters = DataGrid::decodeFiltersString($this->input->getParam('forced_filters'));
}
return $this->_forced_filters;
}
/**
* Sets forced filters for DataGrid. Note that if you call this method with
* non-false argument, then the $_GET param will be ignored
*
* @param Array $_forced_filters_assoc
* @return AdminCRUDController
*/
protected function manuallySetForcedFilters($_forced_filters_assoc)
{
$this->_forced_filters = $_forced_filters_assoc;
return $this;
}
/**
* Returns an instance of Generic_model used for data manipulation
*
* @return Generic_model
*/
protected function getModel()
{
if ($this->getFeedObject()) {
return $this->getFeedObject();
} else {
$this->Generic_model->setTable($this->getTable());
return $this->Generic_model;
}
}
/**
* DataGrid formatting function
*
* @param String $content
* @param Object $line
* @return string
*/
public function _datagrid_format_id_metadata_column($content, &$line)
{
// TODO move HTML out of this method
// $content is usually meta_order_field
$id_field_name = &$this->id_field_name;
$out = '<div class="nowrap">';
if ($this->meta_image_field) {
$is_real_image = false;
$image_field_name = $this->meta_image_field;
if (!is_array($this->meta_image_field) && isset($line->$image_field_name) && $line->$image_field_name) {
// Determining image extension
$image_extension = explode('.', $line->$image_field_name);
if (count($image_extension) > 1) {
$image_extension = end($image_extension);
$image_extension = strtolower($image_extension);
} else {
$image_extension = false;
}
$image_path = 'pepiscms/theme/img/ajaxfilemanager/broken_image_50.png';
$is_real_image = false;
if (in_array($image_extension, array('jpg', 'jpeg', 'png', 'bmp', 'tiff'))) {
$is_real_image = true;
}
if ($is_real_image) {
$image_path = 'admin/ajaxfilemanager/thumb/' . $this->getRelativeUploadsPath() . $line->$image_field_name;
} elseif (file_exists(APPPATH . '/../theme/file_extensions/file_extension_' . $image_extension . '.png')) {
$image_path = 'pepiscms/theme/file_extensions/file_extension_' . $image_extension . '.png';
}
$image_out = '<img class="image" data-src="' . $image_path . '" alt="" />';
} elseif (is_callable($this->meta_image_field)) {
$image_field_name = call_user_func_array($this->meta_image_field, array($content, &$line));
if ($image_field_name) {
$image_out = '<img class="image" data-src="' . admin_url() . 'ajaxfilemanager/thumb/' . $this->getRelativeUploadsPath() . $image_field_name . '" alt="" />';
} else {
$image_out = '<img class="image" src="pepiscms/theme/img/dialog/datagrid/noimage_50.png" alt="" />';
}
} else {
$image_out = '<img class="image" src="pepiscms/theme/img/dialog/datagrid/noimage_50.png" alt="" />';
}
$out .= '<div class="image' . (!$is_real_image ? ' image_like' : '') . '">' . $image_out . '</div>';
}
$out .= '<div class="details">';
$title = $this->getCompiledTitle($content, $line);
if ($title) {
$out .= '<span class="title">' . htmlentities($title, ENT_COMPAT, 'UTF-8') . '</span>';
}
$out .= '<span class="description">';
$description = $this->getCompiledDescription($content, $line);
/* Actions */
$action_out = '';
$running_module = $this->getAttribute('running_module');
if ($this->isPreviewable() && SecurityManager::hasAccess($running_module, 'preview', $running_module)) {
$action_out .= '<a href="' . $this->getModuleBaseUrl() . 'preview/id-' . $line->$id_field_name . $this->getCommonPathParamsString() . '" class="preview ' . (($this->isPopupEnabled()) ? 'popup' : '') . '">' . $this->lang->line('crud_label_preview') . '</a>';
}
if ($this->isEditable() && $this->is_edit_action_displayed_in_grid && SecurityManager::hasAccess($running_module, 'edit', $running_module)) {
$action_out .= '<a href="' . $this->getModuleBaseUrl() . 'edit/id-' . $line->$id_field_name . $this->getCommonPathParamsString() . '" class="edit ' . (($this->isPopupEnabled()) ? 'popup' : '') . '">' . $this->lang->line('crud_label_modify') . '</a>';
}
if ($this->isDeletable() && SecurityManager::hasAccess($running_module, 'delete', $running_module)) {
$action_out .= '<a href="' . $this->getModuleBaseUrl() . 'delete/id-' . $line->$id_field_name . $this->getCommonPathParamsString() . '" class="ask_for_confirmation delete">' . $this->lang->line('crud_label_delete') . '</a>';
}
if ($this->isJournaleable() && SecurityManager::hasAccess($running_module, 'revisions', $running_module)) {
$action_out .= '<a href="' . $this->getModuleBaseUrl() . 'revisions/id-' . $line->$id_field_name . $this->getCommonPathParamsString() . '" class="revisions popup" title="' . $this->lang->line('crud_revisions_show') . '">' . $this->lang->line('crud_revisions_show') . '</a>';
}
foreach ($this->datagrid_meta_actions as &$action) {
if (is_callable($action['label_pattern'])) {
$label = call_user_func_array($action['label_pattern'], array($content, &$line));
} else {
$label = PatternCompiler::compile($action['label_pattern'], $line, $action['label_pattern_keys']);
}
if (is_callable($action['link_pattern'])) {
$link = call_user_func_array($action['link_pattern'], array($content, &$line));
if (!$link) {
continue;
}
} else {
$link = PatternCompiler::compile($action['link_pattern'], $line, $action['link_pattern_keys']);
}
$action_out .= '<a href="' . $link . '" class="' . $action['css_class'] . ' ' . ($action['is_popup'] ? ' popup' : '') . '" ' . ($action['target'] ? 'target="' . $action['target'] . '"' : '') . '>' . $label . '</a>';
}
if ($description) {
$out .= htmlentities($description, ENT_COMPAT, 'UTF-8');
if ($action_out) {
$out .= ' - ';
}
}
if ($action_out) {
$out .= '<span class="separable">' . $action_out . '</span>';
}
$out .= '</span>' .
'</div></div>';
return $out;
}
/**
* Returns compiled title for given line
*
* @param String $content
* @param String $line
* @return string
*/
protected function getCompiledTitle($content, $line)
{
if (!$this->meta_title_pattern) {
return '';
}
if (is_callable($this->meta_title_pattern)) {
$title = call_user_func_array($this->meta_title_pattern, array($content, &$line));
} else {
$title = PatternCompiler::compile($this->meta_title_pattern, $line, $this->meta_title_pattern_keys);
}
return $title;
}
/**
* Returns compiled description for given line
*
* @param String $content
* @param String $line
* @return string
*/
protected function getCompiledDescription($content, $line)
{
if (!$this->meta_description_pattern && !$this->meta_description_pattern_callback) {
return '';
}
if (!$this->meta_description_pattern) {
// description_pattern_callback was previously defined
$title = call_user_func_array($this->meta_description_pattern_callback, array($content, &$line));
} else {
$title = PatternCompiler::compile($this->meta_description_pattern, $line, $this->meta_description_pattern_keys);
if ($this->meta_description_pattern_callback) {
$title = call_user_func_array($this->meta_description_pattern_callback, array($title, &$line));
}
}
return $title;
}
/**
* Compiles pattern, if keys to be replaced are specified, then the script will not parse pattern (faster)
*
* @param $pattern
* @param $object_with_data
* @param array $keys_to_be_replaced
* @return string
* @deprecated as PepisCMS 1.0.0
*/
protected static function compilePattern($pattern, $object_with_data, $keys_to_be_replaced = array())
{
trigger_error('AdminCRUDController::compilePattern() is deprecated.', E_USER_DEPRECATED);
return PatternCompiler::compile($pattern, $object_with_data, $keys_to_be_replaced);
}
/**
* Tells whether journaling is enabled
*
* @return bool
*/
protected function isJournaleable()
{
// TODO implement Interface
if (!method_exists($this->getModel(), 'getJournalingIsEnabled')) {
return false;
}
return $this->getModel()->getJournalingIsEnabled() && $this->getModel()->getJournalingTable();
}
/**
* Crud READ action
* @param bool $display_view
*/
public function index($display_view = true)
{
$running_module = $this->getAttribute('running_module');
$definition = $this->getDefinition();
// Removing keys that should not be displayed
$forced_filters = $this->getForcedFilters();
if (count($forced_filters)) {
foreach ($forced_filters as $field_name => $value) {
if (!isset($definition[$field_name])) {
continue;
}
unset($definition[$field_name]);
$this->datagrid->applyFilter($field_name, $value);
}
}
// Adding an extra virtual field containing metadata
$definition = array_merge(array('id_metadata' => array(
'field' => $this->meta_order_field,
'label' => $this->meta_order_field_label,
'grid_formating_callback' => array($this, '_datagrid_format_id_metadata_column'),
)), $definition);
// Adding arrows move up and down links for an orderable CRUD
if ($this->isOrderable() && SecurityManager::hasAccess($running_module, 'move', $running_module)) {
// Reading the label from datagrid definition
$item_order_column_label = false;
if (isset($definition[$this->item_order_column]['label'])) {
$item_order_column_label = $definition[$this->item_order_column]['label'];
}
// Adding an extra virtual field
$definition = array_merge($definition, array(array(
'field' => $this->item_order_column,
'label' => $item_order_column_label,
'grid_formating_callback' => array($this, '_datagrid_format_item_order_column'),
'grid_css_class' => 'medium',
)));
}
// Adding starable link for a starable CRUD
if ($this->isStarable()) {
// If there was no label set, reading the label from datagrid definition
if (!$this->is_stared_label) {
if (isset($definition[$this->is_stared_column]['label'])) {
$this->is_stared_label = $definition[$this->is_stared_column]['label'];
}
}
// Adding an extra virtual field
$definition = array_merge($definition, array(array(
'field' => $this->is_stared_column,
'label' => $this->is_stared_label,
'grid_formating_callback' => array($this, '_datagrid_format_is_stared_column'),
'grid_css_class' => 'medium',
)));
}
// Adding import link for importable CRUD
if ($this->isImportable()) {
$this->addActionForIndex(array('link' => $this->getModuleBaseUrl() . 'import', 'name' => $this->lang->line('crud_label_import_from_file'), 'icon' => module_resources_url('crud') . 'import_12.png'));
}
// Adding export links for exportable CRUD
if ($this->isExportable()) {
$this->addActionForIndex(array('link' => $this->getModuleBaseUrl() . 'export/format-csv', 'name' => $this->lang->line('crud_label_export') . ' (CSV)', 'icon' => module_resources_url('crud') . 'export_12.png'));
$this->load->library('Spreadsheet');
if ($this->spreadsheet->isFullyEnabled()) {
$this->addActionForIndex(array('link' => $this->getModuleBaseUrl() . 'export/format-xls', 'name' => $this->lang->line('crud_label_export') . ' (XLS - Excel 97)', 'icon' => module_resources_url('crud') . 'export_12.png'))
->addActionForIndex(array('link' => $this->getModuleBaseUrl() . 'export/format-xlsx', 'name' => $this->lang->line('crud_label_export') . ' (XLSX - Excel 2007)', 'icon' => module_resources_url('crud') . 'export_12.png'));
}
}
// Checking if there is a feed object available
if ($this->getFeedObject()) {
// Applying CRUD where to feed object if case
if ($this->getWhere()) {
$this->getFeedObject()->setWhere($this->getWhere());
}
// Seting datagrid feed object if case
$this->datagrid->setFeedObject($this->getFeedObject());
} // Setting table when there is no feed object
else {
$this->datagrid->setTable($this->getTable(), $this->getWhere());
}
// Sometimes redundant but for your own safety leave it like this
$this->id_field_name = $this->datagrid->getFeedObject()->getIdFieldName();
// Prevent glitchs related to FOREIGN_KEY_MANY_TO_MANY datagrid order mechanism
foreach ($definition as &$field_definition) {
// If the field is of relation FOREIGN_KEY_MANY_TO_MANY
if (isset($field_definition['foreign_key_relationship_type']) && $field_definition['foreign_key_relationship_type'] == FormBuilder::FOREIGN_KEY_MANY_TO_MANY) {
// If there was no grid_is_orderable value already set
if (!isset($field_definition['grid_is_orderable'])) {
$field_definition['grid_is_orderable'] = false;
}
}
}
$this->datagrid->setTitle($this->getPageTitle())
->setBaseUrl($this->getModuleBaseUrl() . $this->getMethodName() . ($this->getForcedFilters() ? '/forced_filters-' . DataGrid::encodeFiltersString($this->getForcedFilters()) : '') . ($this->input->getParam('layout') ? '/layout-' . $this->input->getParam('layout') : ''))
->setDefinition($definition);
$this->assign('datagrid', $this->datagrid->generate($this->datagrid_generate_parameter))
->assign('title', $this->getPageTitle())
->assign('add_new_item_label', $this->getAddNewItemLabel())
->assign('is_addable', $this->isAddable())
->assign('tooltip_text', $this->tooltip_text_for_index)
->assign('is_popup_enabled', $this->isPopupEnabled())
->assign('actions', $this->actions_for_index)
->assign('back_action_for_index', $this->back_action_for_index)
->assign('module_name', $this->getModuleName())
->assign('method_name', $this->getMethodName())
->assign('module_base_url', $this->getModuleBaseUrl())
->assign('forced_filters', $this->getForcedFilters())
->assign('layout', $this->input->getParam('layout'))
->assign('filters', $this->input->getParam('filters'))
->assign('order', $this->input->getParam('order'))
->assign('order_by', $this->input->getParam('order_by'));
// Displaying
if (!$display_view) {
return;
}
if (file_exists($this->current_module_template_path . 'index.php')) {
$this->display($this->current_module_template_path . 'index.php');
} else {
$this->display($this->getTemplatePath() . 'index.php');
}
}
/**
* Restore field action
*
* @return void
*/
public function revisionrestorefield()
{
$id = $this->input->getParam('id');
$revision_id = $this->input->getParam('revision_id');
$field = $this->input->getParam('field');
if (!$id || !$revision_id || !$field || !$this->isJournaleable()) {
show_404();
}
$revision = $this->getModel()->journalingGetById($id, $revision_id);
if (!$revision || !isset($revision->$field)) {
show_404();
}
$data = array(
$field => $revision->$field,
);
$success = $this->getModel()->saveById($id, $data);
if ($this->input->getParam('layout') == 'popup') {
if ($success) {
return $this->_closePopupAndDisplaySuccess('crud_revision_field_successfully_restored');
} else {
$this->_closePopup();
}
} else {
if ($success) {
$this->load->library('SimpleSessionMessage');
$this->simplesessionmessage->setFormattingFunction(SimpleSessionMessage::FUNCTION_SUCCESS)
->setMessage('crud_revision_field_successfully_restored');
}
redirect($this->getModuleBaseUrl() . 'revisions/id-' . $id . ($this->getForcedFilters() ? '/forced_filters-' . DataGrid::encodeFiltersString($this->getForcedFilters()) : '') . ($this->input->getParam('layout') ? '/layout-' . $this->input->getParam('layout') : ''));
}
}
/**
* Revision preview action
*/
public function revision()
{
$id = $this->input->getParam('id');
$revision_id = $this->input->getParam('revision_id');
if (!$id || !$revision_id || !$this->isJournaleable()) {
show_404();
}
$revision = $this->getModel()->journalingGetById($id, $revision_id);
$revision_current = $this->getModel()->journalingGetById($id);
$key_names = array();
$definition = $this->getDefinition();
foreach ($definition as $key => $field_definition) {
if (isset($field_definition['label'])) {
$key_names[$key] = $field_definition['label'];
}
}
// Detecting whether the file is identical
$is_identical = true;
foreach ($revision as $key => $value) {
if ($revision_current->$key != $revision->$key) {
$is_identical = false;
break;
}
}
$this->assign('id', $id)
->assign('title', $this->getPageTitle())
->assign('revision_id', $revision_id)
->assign('revision', $revision)
->assign('revision_current', $revision_current)
->assign('key_names', $key_names)
->assign('is_identical', $is_identical)
->assign('module_name', $this->getModuleName());
if (file_exists($this->current_module_template_path . 'revision.php')) {
$this->display($this->current_module_template_path . 'revision.php');
} else {
$this->display($this->getTemplatePath() . 'revision.php');
}
}
/**
* Revisions list action
*/
public function revisions()
{
$id = $this->input->getParam('id');
if (!$id || !$this->isJournaleable()) {
show_404();
}
$this->assign('id', $id)
->assign('title', $this->getPageTitle())
->assign('revision_summary', $this->getModel()->journalingGetRevisionSummary($id))
->assign('back_to_items_label', $this->getBackToItemsLabel())
->assign('back_link_for_edit', $this->getBackLinkForEdit())
->assign('module_name', $this->getModuleName());
if (file_exists($this->current_module_template_path . 'revisions.php')) {
$this->display($this->current_module_template_path . 'revisions.php');
} else {
$this->display($this->getTemplatePath() . 'revisions.php');
}
}
/**
* CRUD create/update action
* @param bool $display_view
*/
public function edit($display_view = true)
{
$id = $this->input->getParam('id');
if ($id && !$this->isEditable()) {
show_404();
}
if (!$id && !$this->isAddable()) {
show_404();
}
if ($id) {
$this->formbuilder->setTitle($this->lang->line('crud_label_modify'));
} else {
$this->formbuilder->setTitle($this->getAddNewItemLabel());
}
if ($this->input->getParam('layout') == 'popup' && $this->input->getParam('direct')) {
$this->formbuilder->setCallback(array($this, '_fb_callback_popup_close'), FormBuilder::CALLBACK_AFTER_SAVE);
}
//$this->formbuilder->setReadOnly( false );
$this->_edit(false, $display_view);
}
/**
* This method is called by edit or preview
* @param bool $is_preview
* @param bool $display_view
*/
protected function _edit($is_preview = false, $display_view = true)
{
$forced_filters = $this->getForcedFilters();
$definition = $this->getDefinition();
$id = $this->input->getParam('id');
foreach ($forced_filters as $field_name => $value) {
if (!isset($definition[$field_name])) {
continue;
}
//unset($definition[$field_name]);
$definition[$field_name]['input_is_editable'] = false;
$definition[$field_name]['input_default_value'] = $value;
$definition[$field_name]['filter_type'] = false;
}
$this->formbuilder->setId($id)
->setBackLink($this->getBackLinkForEdit() . ($this->getForcedFilters() ? '/forced_filters-' . DataGrid::encodeFiltersString($this->getForcedFilters()) : '') . ($this->input->getParam('layout') ? '/layout-' . $this->input->getParam('layout') : ''))
->formbuilder->setDefinition($definition);
if ($this->getFeedObject()) {
$this->formbuilder->setFeedObject($this->getFeedObject());
} else {
$this->formbuilder->setTable($this->getTable(), $this->formbuilder->getFieldNames());
}
if ($id && $this->isJournaleable()) {
$this->addActionForEdit(array('link' => $this->getModuleBaseUrl() . 'revisions/id-' . $id, 'name' => $this->lang->line('crud_revisions_show'), 'icon' => module_resources_url('crud') . 'revision_16.png', 'class' => 'popup'));
}
// Note: this must be called before getObject() method
$form = $this->formbuilder->generate();
// Showing 404 for wrong IDs for edit/preview pages
if ($id && !$this->formbuilder->getObject()) {
show_404();
}
$this->assign('form', $form)
->assign('id', $id)
->assign('is_preview', $is_preview)
->assign('is_editable', $this->isEditable())
->assign('is_previewable', $this->isPreviewable())
->assign('title', $this->getPageTitle())
->assign('back_to_items_label', $this->getBackToItemsLabel())
->assign('back_link_for_edit', $this->getBackLinkForEdit())
->assign('actions', $this->actions_for_edit)
->assign('module_name', $this->getModuleName());
if (!$is_preview) {
// This should be defined after the form is generated - this allows to be changed using form callbacks
$this->assign('tooltip_text', $this->tooltip_text_for_edit);
}
// Displaying
if (!$display_view) {
return;
}
if (file_exists($this->current_module_template_path . 'edit.php')) {
$this->display($this->current_module_template_path . 'edit.php');
} else {
$this->display($this->getTemplatePath() . 'edit.php');
}
}
/**
* Export action
*/
public function export()
{
if (!$this->isExportable()) {
show_404();
}
$format = $this->input->getParam('format');
if (!in_array($format, array('csv', Spreadsheet::EXCEL_XLS, Spreadsheet::EXCEL_XLSX))) {
show_404();
}
$this->load->library('Spreadsheet');
if (!$this->spreadsheet->isFullyEnabled() && in_array($format, array(Spreadsheet::EXCEL_XLS, Spreadsheet::EXCEL_XLSX))) {
show_error('Spreadsheet::EXCEL_XLS and Spreadsheet::EXCEL_XLSX spreadsheets are not supported.');
}
// getting data
$result = $this->getModel()->getAdvancedFeed('*', 0, 999999, $this->getModel()->getIdFieldName(), 'ASC', array(), false);
$result = $result[0];
// caching variable, we dont want is_callable to be executed for every row
$is_callable = is_callable($this->is_exportable_data_formatting_callback);
$export_result = array();
foreach ($result as &$line) {
// transforming object into array
$line_data = (array)$line;
unset($line); // saving some memory
// applying formatting callback if case
if ($is_callable) {
$line_data = call_user_func_array($this->is_exportable_data_formatting_callback, array($line_data));
}
// building export array
$export_result[] = $line_data;
}
// exporting into desired format
$file_name = ($this->getModel()->getTable() ? $this->getModel()->getTable() : $this->getModuleName()) . '-' . date('Y-m-d-h-i-s');
if ($format == 'csv') {
$this->spreadsheet->generateCSV($export_result, false, $file_name . '.csv');
} elseif ($format == Spreadsheet::EXCEL_XLS) {
$this->spreadsheet->generateExcel($export_result, false, $file_name . '.xls', true, true, Spreadsheet::EXCEL_XLS);
} elseif ($format == Spreadsheet::EXCEL_XLSX) {
$this->spreadsheet->generateExcel($export_result, false, $file_name . '.xlsx', true, true, Spreadsheet::EXCEL_XLSX);
}
}
/**
* Import action
*/
public function import()
{
if (!$this->isImportable()) {
show_404();
}
$cache_path = $this->config->item('cache_path');
$cache_path = ($cache_path === '') ? 'application/cache/' : $cache_path;
if ($cache_path[0] !== '/') {
$cache_path = INSTALLATIONPATH . $cache_path;
}
$cache_path .= 'tmp/';
$this->load->library('FormBuilder');
$this->load->library('Spreadsheet');
$this->formbuilder->clear()
->setTitle($this->lang->line('crud_label_import'))
->setSubmitLabel($this->lang->line('crud_label_import_from_file'))
->setCallback(array($this, '_fb_callback_on_import'), FormBuilder::CALLBACK_ON_SAVE)
->setBackLink($this->getModuleBaseUrl()); // TODO Add applied filters to the back link, the same as edit
$upload_allowed_types = 'csv';
if ($this->spreadsheet->isFullyEnabled()) {
$description_key = 'crud_file_to_import_description_fully_enabled';
$upload_allowed_types .= '|xls|xlsx';
$tip_key = 'crud_label_import_tip_fully_enabled';
} else {
$description_key = 'crud_file_to_import_description';
$tip_key = 'crud_label_import_tip';
}
$this->formbuilder->setDefinition(array(
'file_to_import' => array(
'upload_path' => $cache_path,
'show_in_grid' => false,
'show_in_form' => true,
'input_type' => FormBuilder::FILE,
'upload_allowed_types' => $upload_allowed_types,
'validation_rules' => '',
'label' => $this->lang->line('crud_file_to_import'),
'description' => $this->lang->line($description_key),
),
'commit' => array(
'input_type' => FormBuilder::HIDDEN,
'input_default_value' => 1,
)
));
$this->assign('tip', sprintf($this->lang->line($tip_key), implode(', ', $this->getModel()->getAcceptedPostFields()), $this->getModel()->getIdFieldName()))
->assign('title', $this->getPageTitle())
->assign('back_to_items_label', $this->getBackToItemsLabel())
->assign('back_link_for_edit', $this->getBackLinkForEdit())
->assign('formbuilder', $this->formbuilder->generate())
->assign('module_name', $this->getModuleName());
if (file_exists($this->current_module_template_path . 'import.php')) {
$this->display($this->current_module_template_path . 'import.php');
} else {
$this->display($this->getTemplatePath() . 'import.php');
}
}
/**
* CRUD read
* @param bool $display_view
*/
public function preview($display_view = true)
{
if (!$this->isPreviewable()) {
show_404();
}
$this->formbuilder->setTitle($this->lang->line('crud_label_preview'))
->setReadOnly();
$this->_edit(true, $display_view);
}
/**
* Moves items by changing their item order
*/
public function move()
{
$direction = $this->input->getParam('direction') == 'down' ? 'down' : 'up';
$id = $this->input->getParam('id');
if (!$id) {
show_404();
}
$success = $this->getModel()->move($id, $direction, $this->getTable(), $this->getItemOrderConstraintColumn(), $this->getItemOrderColumn(), $this->getIdFieldName());
if ($this->input->getParam('json') == 1) {
if ($success) {
die(json_encode(array('status' => 1, 'message' => 'OK')));
} else {
die(json_encode(array('status' => 0, 'message' => 'No change')));
}
}
$this->redirectBack();
}
/**
* Deleting item
*/
public function delete()
{
$id = $this->input->getParam('id');
if (!$id || !$this->is_deletable) {
show_404();
}
// getting full item to execute full delete procedure
$item = $this->getModel()->getById($id);
$this->_onDelete($id, $item);
$success = $this->getModel()->deleteById($id);
if ($this->input->getParam('json') == 1) {
if ($success) {
die(json_encode(array('status' => 1, 'message' => 'OK')));
} else {
die(json_encode(array('status' => 0, 'message' => 'Unable to delete')));
}
}
if ($success) {
$this->simplesessionmessage->setFormattingFunction(SimpleSessionMessage::FUNCTION_SUCCESS)
->setMessage('global_header_success');
} else {
$this->simplesessionmessage->setFormattingFunction(SimpleSessionMessage::FUNCTION_WARNING)
->setMessage('crud_unable_to_delete');
}
$this->redirectBack();;
}
/**
* Sets the star flag to true/false
*/
public function star()
{
$id = $this->input->getParam('id');
if (!$id || !$this->is_starable) {
show_404();
}
$is_stared = $this->input->getParam('toggle');
if ($is_stared != 1) {
$is_stared = 0;
}
// Updating
$this->db->set($this->is_stared_column, $is_stared)
->where($this->getIdFieldName(), $id)
->update($this->getTable());
if ($this->input->getParam('json') == 1) {
die(json_encode(array('status' => 1, 'message' => 'OK')));
}
$this->simplesessionmessage->setFormattingFunction(SimpleSessionMessage::FUNCTION_SUCCESS)
->setMessage('global_header_success');
$this->redirectBack();
}
/**
* Handles import file upload and parsing
*
* @param array $data_array
* @return bool
* @throws PHPExcel_Exception
* @throws PHPExcel_Reader_Exception
*/
public function _fb_callback_on_import($data_array)
{
$this->load->library('Spreadsheet');
$this->load->helper('url');
// checking if there was a file submited
if (!isset($data_array['file_to_import']) || !$data_array['file_to_import']) {
$this->formbuilder->setValidationErrorMessage($this->lang->line('crud_no_file_uploaded_or_wrong_filetype'));
return false;
}
// building file path
$cache_path = $this->config->item('cache_path');
$cache_path = ($cache_path === '') ? 'application/cache/' : $cache_path;
if ($cache_path[0] !== '/') {
$cache_path = INSTALLATIONPATH . $cache_path;
}
$cache_path .= 'tmp/';
$file = $cache_path . $data_array['file_to_import'];
//file_put_contents($file, iconv('ASCII', 'UTF-8//IGNORE', file_get_contents($file)));
// just in case
if (!file_exists($file)) {
$this->formbuilder->setValidationErrorMessage($this->lang->line('crud_imported_file_does_not_exist'));
return false;
}
// parsing file based on file extension
$ext_arts = explode('.', $file);
$ext = strtolower(end($ext_arts));
if ($ext == 'xls' || $ext == 'xlsx') {
if (!$this->spreadsheet->isFullyEnabled()) {
$this->formbuilder->setValidationErrorMessage($this->lang->line('crud_import_excel_not_fully_enabled'));
return false;
} else {
$result = $this->spreadsheet->parseExcel($file);
}
} elseif ($ext == 'csv') {
$result = $this->spreadsheet->parseCSV($file);
}
// no longer needed, security reasons
unlink($file);
// empty file, show warning
if (!count($result)) {
$this->formbuilder->setValidationErrorMessage(sprintf($this->lang->line('crud_import_empty_spreadsheet'), $ext));
return false;
}
// initializing empty arrays
$update_data = $insert_data = array();
// we need it to filter user input
$accepted_fields = $this->getModel()->getAcceptedPostFields();
// we need it to decide whether to use insert or update queries
$id_field_name = $this->getModel()->getIdFieldName();
// We need it for updates as well
$accepted_fields[] = $id_field_name;
// caching variable, we dont want is_callable to be executed for every row
$is_callable = is_callable($this->is_importable_data_formatting_callback);
// for every line of submited data
foreach ($result as $line) {
$data = array();
// automatic adjustments
foreach ($accepted_fields as $field_name) {
if (isset($line[$field_name])) {
$data[$field_name] = trim($line[$field_name]);
if (in_array($field_name, array('www', 'website', 'url', 'web_site'))) {
$data[$field_name] = prep_url($data[$field_name]);
}
if (in_array($field_name, array('email', 'e_mail'))) {
$data[$field_name] = strtolower($data[$field_name]);
}
}
}
// filtering input, there are some fields that must be set, we do not care about the rest
if ($this->is_importable_must_have_fields && is_array($this->is_importable_must_have_fields)) {
$continue = false;
foreach ($this->is_importable_must_have_fields as $must_have_field) {
if (!isset($data[$must_have_field]) || !strlen($data[$must_have_field])) {
$continue = true;
break;
}
}
if ($continue) {
continue;
}
}
// callback modifier
if ($is_callable) {
$data = call_user_func_array($this->is_importable_data_formatting_callback, array($data, &$line));
}
// extra protection
if (!$data) {
continue;
}
// preparing data for separate insert and update queries
if (isset($data[$id_field_name]) && $data[$id_field_name]) {
$update_data[] = $data;
} else {
foreach ($accepted_fields as $field_name) {
if (!isset($data[$field_name])) {
$data[$field_name] = null;
}
}
$insert_data[] = $data;
}
}
$count_insert = count($insert_data);
$count_update = count($update_data);
$affected_rows = 0;
// doing batch insert
if ($count_insert > 0) {
$this->db->insert_batch($this->getModel()->getTable(), $insert_data);
$affected_rows += $this->db->affected_rows();
}
// doing batch update
if ($count_update > 0) {
$this->db->update_batch($this->getModel()->getTable(), $update_data, $id_field_name);
$affected_rows += $this->db->affected_rows();
}
if (($count_insert + $count_update) == 0) {
$this->formbuilder->setValidationErrorMessage($this->lang->line('crud_import_nonempry_spreadsheet_but_nothing_to_update'));
return false;
}
if ($affected_rows == 0) {
$this->formbuilder->setValidationErrorMessage(sprintf($this->lang->line('crud_import_no_rows_affected'), $count_insert, $count_update));
return false;
}
// great
return true;
}
/**
* Closing action for popup windows
*
* @param $data
*/
public function _fb_callback_popup_close(&$data)
{
return $this->_closePopupAndDisplaySuccess();
}
/**
* Prints popup close code and sets session message
*
* @param string $message
*/
public function _closePopupAndDisplaySuccess($message = 'global_header_success')
{
$this->load->library('SimpleSessionMessage');
$this->simplesessionmessage->setFormattingFunction(SimpleSessionMessage::FUNCTION_SUCCESS)
->setMessage($message);
$this->_closePopup();
}
/**
* Prints popup close code
* @param bool $return
* @return string
*/
protected function _closePopup($return = false)
{
$out = ob_get_contents();
if ($out) {
die(); // This is not necessarely but helps to debug the system in case there are errors on save
}
$this->load->helper('popup');
$out = popup_close_html();
if ($return) {
return $out;
}
// Else
die($out);
}
/**
* Overwrite this function if you want to remove extra items such as files
* @param $id
* @param $item
*/
public function _onDelete($id, $item)
{
// By default this method is empty, it should be overwritten by inheriting class
}
/**
* Datagrid callback
*
* @param String $content
* @param Object $line
* @return String html
*/
public function _datagrid_format_is_stared_column($content, &$line)
{
$id_field_name = &$this->id_field_name;
if ($content == 1) {
return '<a href="' . $this->getModuleBaseUrl() . 'star/id-' . $line->$id_field_name . ($this->getForcedFilters() ? '/forced_filters-' . DataGrid::encodeFiltersString($this->getForcedFilters()) : '') . ($this->input->getParam('layout') ? '/layout-' . $this->input->getParam('layout') : '') . '" class="toggle off"><span>x</span></a>';
}
return '<a href="' . $this->getModuleBaseUrl() . 'star/id-' . $line->$id_field_name . ($this->getForcedFilters() ? '/forced_filters-' . DataGrid::encodeFiltersString($this->getForcedFilters()) : '') . ($this->input->getParam('layout') ? '/layout-' . $this->input->getParam('layout') : '') . '" class="toggle on"><span>v</span></a>';
}
/**
* Datagrid callback
*
* @param String $content
* @param Object $line
* @return String html
*/
public function _datagrid_format_item_order_column($content, &$line)
{
$id_field_name = &$this->id_field_name;
$o = $this->datagrid->getOrder();
$order_by = $o['order_by'];
$order = $o['order'];
if (($order_by == $this->getItemOrderColumn() || $order_by == '') && count($this->datagrid->getFilterPairs()) == 0) {
if ($order == 'ASC' || $order == '') {
$up = 'up';
$down = 'down';
} else {
$up = 'down';
$down = 'up';
}
return '<a href="' . $this->getModuleBaseUrl() . '/move/id-' . $line->$id_field_name . '/direction-' . $up . ($this->getForcedFilters() ? '/forced_filters-' . DataGrid::encodeFiltersString($this->getForcedFilters()) : '') . ($this->input->getParam('layout') ? '/layout-' . $this->input->getParam('layout') : '') . '" class="moveUp json"><img src="pepiscms/theme/img/dialog/datagrid/up_16.png" alt="" /></a> <a href="' . $this->getModuleBaseUrl() . '/move/id-' . $line->$id_field_name . '/direction-' . $down . '" class="moveDown json"><img src="pepiscms/theme/img/dialog/datagrid/down_16.png" alt="" /></a>';
} else {
return $content;
}
}
private function redirectBack()
{
$this->load->library('User_agent');
if ($this->agent->referrer()) {
redirect($this->agent->referrer());
} else {
redirect($this->getModuleBaseUrl());
}
}
protected function getCommonPathParamsString()
{
return ($this->input->getParam('order_by') ? '/order_by-' . $this->input->getParam('order_by') : '') .
($this->input->getParam('order') ? '/order-' . $this->input->getParam('order') : '') .
($this->input->getParam('filters') ? '/filters-' . $this->input->getParam('filters') : '') .
($this->getForcedFilters() ? '/forced_filters-' . DataGrid::encodeFiltersString($this->getForcedFilters()) : '') .
($this->input->getParam('layout') ? '/layout-' . $this->input->getParam('layout') : '');
}
/**
* @return bool|string
*/
private function getRelativeUploadsPath()
{
$uploads_path = $this->config->item('uploads_path');
if (strpos($this->meta_image_base_url, $uploads_path) === 0) {
return substr($this->meta_image_base_url, strlen($uploads_path));
}
return $this->meta_image_base_url;
}
}