PageRenderTime 188ms CodeModel.GetById 95ms app.highlight 77ms RepoModel.GetById 3ms app.codeStats 1ms

/fuel/modules/fuel/controllers/module.php

https://github.com/jamiegrand/FUEL-CMS
PHP | 2196 lines | 1570 code | 352 blank | 274 comment | 215 complexity | 3bd821c5ec692350b17014ffd41530ad MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1<?php
   2require_once(FUEL_PATH.'/libraries/Fuel_base_controller.php');
   3
   4class Module extends Fuel_base_controller {
   5	
   6	public $module_obj; // the module object
   7	public $module = ''; // the name of the module
   8	public $uploaded_data = array(); // reference to the uploaded data
   9
  10	protected $_orig_post = array(); // used for reference
  11	
  12	function __construct($validate = TRUE)
  13	{
  14		parent::__construct($validate);
  15
  16		$this->load->module_model(FUEL_FOLDER, 'fuel_archives_model');
  17		if (empty($this->module))
  18		{
  19			$this->module = fuel_uri_segment(1);
  20		}
  21
  22		if (empty($this->module))
  23		{
  24			show_error(lang('cannot_determine_module'));
  25		}
  26		
  27		$params = array();
  28		if ($this->fuel->modules->exists($this->module, FALSE))
  29		{
  30			$this->module_obj = $this->fuel->modules->get($this->module, FALSE);
  31			$params = $this->module_obj->info();
  32		}
  33		else if ($this->fuel->modules->exists($this->module.'_'.fuel_uri_segment(2), FALSE))
  34		{
  35			// if it is a module with multiple controllers, then we'll check first and second FUEL segment with an underscore'
  36			$this->module = $this->module.'_'.fuel_uri_segment(2);
  37			if ($this->fuel->modules->exists($this->module, FALSE))
  38			{
  39				$this->module_obj = $this->fuel->modules->get($this->module, FALSE);
  40				$params = $this->module_obj->info();
  41			}
  42		}
  43		else if ($this->fuel->modules->exists(fuel_uri_segment(2), FALSE))
  44		{
  45			$this->module = fuel_uri_segment(2);
  46			$this->module_obj = $this->fuel->modules->get($this->module, FALSE);
  47
  48			if ($this->module_obj)
  49			{
  50				$mod_name = $this->module_obj->name();	
  51			}
  52			
  53			if (empty($mod_name))
  54			{
  55				show_error(lang('error_missing_module', fuel_uri_segment(1)));
  56			}
  57			unset($mod_name);
  58			$params = $this->module_obj->info();
  59		}
  60
  61		// stop here if the module is disabled
  62		if ($params['disabled'] === TRUE)
  63		{
  64			show_404();
  65		}
  66		foreach($params as $key => $val)
  67		{
  68			$this->$key = $val;
  69		}
  70		
  71		// load any configuration
  72		if (!empty($this->configuration)) 
  73		{
  74			if (is_array($this->configuration))
  75			{
  76				$config_module = key($this->configuration);
  77				$config_file = current($this->configuration);
  78
  79				$this->config->module_load($config_module, $config_file);
  80			}
  81			else
  82			{
  83				$this->config->load($this->configuration);
  84			}
  85		}
  86		
  87		// load any language
  88		if (!empty($this->language)) 
  89		{
  90			if (is_array($this->language))
  91			{
  92				$lang_module = key($this->language);
  93				$lang_file = current($this->language);
  94
  95				// now check to see if we need to load the language file or not... 
  96				// we load the main language file automatically with the Fuel_base_controller.php
  97				$this->load->module_language($lang_module, $lang_file, $this->fuel->auth->user_lang());
  98			}
  99			else
 100			{
 101				$this->load->language($this->language);
 102			}
 103		}
 104		
 105		// load the model
 106		if (!empty($this->model_location))
 107		{
 108			$this->load->module_model($this->model_location, $this->model_name);
 109		}
 110		else
 111		{
 112			$this->load->model($this->model_name);
 113		}
 114		
 115		// get the model name
 116		$model_parts = explode('/', $this->model_name);
 117		$model = end($model_parts);
 118		
 119		
 120		// set the module_uri
 121		if (empty($this->module_uri)) $this->module_uri = $this->module;
 122		
 123		$this->js_controller_params['module'] = $this->module_uri;
 124		
 125
 126		if (!empty($model))
 127		{
 128			$this->model =& $this->$model;
 129		}
 130		else
 131		{
 132			show_error(lang('incorrect_route_to_module'));
 133		}
 134		
 135		// global variables
 136		$vars = array();
 137		if (!empty($params['js']))
 138		{
 139			if (is_string($params['js']))
 140			{
 141				$params['js'] = preg_split("/,\s*/", $params['js']);
 142			}
 143			$vars['js'] = $params['js'];
 144		}
 145		
 146		if (!empty($this->nav_selected)) $vars['nav_selected'] = $this->nav_selected;
 147		$this->load->vars($vars);
 148		
 149		$this->fuel->admin->load_js_localized($params['js_localized']);
 150
 151		if (!empty($this->permission) AND $validate)
 152		{
 153			$this->_validate_user($this->permission);
 154		}
 155		
 156		
 157	}
 158	
 159	// --------------------------------------------------------------------
 160	
 161	/**
 162	 * Displays the list (table) view
 163	 *
 164	 * @access	public
 165	 * @return	void
 166	 */	
 167	function index()
 168	{
 169		$this->items();
 170	}
 171	
 172	// --------------------------------------------------------------------
 173	
 174	/**
 175	 * Displays the list (table) view
 176	 *
 177	 * @access	public
 178	 * @return	void
 179	 */	
 180	function items()
 181	{
 182		$this->load->library('data_table');
 183	
 184		// check the model for a filters method as well and merge it with the property value
 185		// added per http://www.getfuelcms.com/forums/discussion/760/filter-dropdown/#Item_2
 186		if (method_exists($this->model, 'filters'))
 187		{
 188			$this->filters = array_merge($this->filters, $this->model->filters($this->filters));
 189		}
 190
 191		// set the language dropdown if there is a language column
 192		if ($this->fuel->language->has_multiple() AND !empty($this->language_col) AND method_exists($this->model, 'get_languages'))
 193		{
 194			$languages = $this->model->get_languages($this->language_col);
 195			$first_option = current($languages);
 196			if (!empty($languages) AND (is_string($first_option) OR (is_array($first_option)) AND count($first_option) > 1))
 197			{
 198				$lang_filter = array('type' => 'select', 'options' => $languages, 'label' => lang('label_language'), 'first_option' => lang('label_select_a_language'));
 199				$this->filters[$this->language_col.'_equal'] = $lang_filter;
 200				$this->model->add_filter_join($this->language_col.'_equal', 'and');
 201			}
 202		}
 203		
 204		$params = $this->_list_process();
 205		
 206		// save page state
 207		$this->fuel->admin->save_page_state($params);
 208		
 209		
 210		// create search filter
 211		$filters[$this->display_field] = trim($params['search_term']);
 212		
 213		// sort of hacky here... to make it easy for the model to just filter on the search term (like the users model)
 214		$this->model->filter_value = trim($params['search_term']);
 215		foreach($this->filters as $key => $val)
 216		{
 217			$filters[$key] = $params[$key];
 218			if (!empty($val['filter_join']))
 219			{
 220				if (!is_array($this->model->filter_join[$key]))
 221				{
 222					settype($this->model->filter_join, 'array');
 223				}
 224				$this->model->filter_join[$key] = $val['filter_join'];
 225			}
 226		}
 227		
 228		// set model filters before pagination and setting table data
 229		if (method_exists($this->model, 'add_filters'))
 230		{
 231			$this->model->add_filters($filters);
 232		}
 233	
 234		// to prevent it from being called unecessarility with ajax
 235		if (!is_ajax())
 236		{
 237			$this->config->set_item('enable_query_strings', FALSE);
 238		
 239			// pagination
 240			$query_str_arr = $this->input->get(NULL, TRUE);
 241			unset($query_str_arr['offset']);
 242			$query_str = (!empty($query_str_arr)) ? http_build_query($query_str_arr) : '';
 243		
 244			$config['base_url'] = fuel_url($this->module_uri).'/items/?'.$query_str;
 245			$uri_segment = 4 + (count(explode('/', $this->module_uri)) - 1);
 246			$config['total_rows'] = $this->model->list_items_total();
 247			$config['uri_segment'] = fuel_uri_index($uri_segment);
 248			$config['per_page'] = (int) $params['limit'];
 249			$config['query_string_segment'] = 'offset';
 250			$config['page_query_string'] = TRUE;
 251			$config['num_links'] = 5;
 252		
 253			$config['prev_link'] = lang('pagination_prev_page');
 254			$config['next_link'] = lang('pagination_next_page');
 255			$config['first_link'] = lang('pagination_first_link');
 256			$config['last_link'] = lang('pagination_last_link');
 257		
 258			// must reset these in case a config file has something different
 259			$config['full_tag_open'] = NULL;
 260			$config['full_tag_close'] = NULL;
 261			$config['full_tag_close'] = NULL;
 262			$config['num_tag_open'] = '&nbsp;';
 263			$config['num_tag_close'] = NULL;
 264			$config['cur_tag_open'] = '&nbsp;<strong>';
 265			$config['cur_tag_close'] = '</strong>';
 266			$config['next_tag_open'] = '&nbsp;';
 267			$config['next_tag_close'] = '&nbsp;';
 268			$config['prev_tag_open'] = '&nbsp;';
 269			$config['prev_tag_close'] = NULL;
 270			$config['first_tag_open'] = '&nbsp;';
 271			$config['first_tag_close'] = '&nbsp;';
 272			$config['last_tag_open'] = NULL;
 273			$config['last_tag_close'] = NULL;
 274			$this->pagination->initialize($config);
 275
 276			if (method_exists($this->model, 'tree'))
 277			{
 278				//$vars['tree'] = "Loading...\n<ul></ul>\n";
 279				$vars['tree'] = "\n<ul></ul>\n";
 280			}
 281			
 282			// reset offset if total rows is less then limit
 283			if ($config['total_rows'] < $params['limit'])
 284			{
 285				$params['offset'] = 0;
 286			}
 287
 288			
 289		}
 290		// set vars
 291		$vars['params'] = $params;
 292		
 293		$vars['table'] = '';
 294		
 295		
 296
 297		// reload table
 298		if (is_ajax())
 299		{
 300			// data table items... check col value to know if we want to send sorting parameter
 301			if (empty($params['col']) OR empty($params['order']))
 302			{
 303				$items = $this->model->list_items($params['limit'], $params['offset']);
 304			}
 305			else
 306			{
 307				$items = $this->model->list_items($params['limit'], $params['offset'], $params['col'], $params['order']);
 308				$this->data_table->set_sorting($params['col'], $params['order']);
 309			}
 310
 311			$has_edit_permission = $this->fuel->auth->has_permission($this->permission, "edit") ? '1' : '0';
 312			$has_delete_permission = $this->fuel->auth->has_permission($this->permission, "delete") ? '1' : '0';
 313			
 314			// set data table actions... look first for item_actions set in the fuel_modules
 315			$edit_func = '
 316			$CI =& get_instance();
 317			$link = "";';
 318			if ($has_edit_permission)
 319			{
 320				$edit_func .= 'if (isset($cols[$CI->model->key_field()]))
 321				{
 322					$url = fuel_url("'.$this->module_uri.'/edit/".$cols[$CI->model->key_field()]);
 323					$link = "<a href=\"".$url."\" class=\"action_delete\">".lang("table_action_delete")."</a>";
 324					$link .= " <input type=\"checkbox\" name=\"delete[".$cols[$CI->model->key_field()]."]\" value=\"1\" id=\"delete_".$cols[$CI->model->key_field()]."\" class=\"multi_delete\"/>";
 325				}';	
 326			}
 327			$edit_func .= 'return $link;';
 328			
 329			$edit_func = create_function('$cols', $edit_func);
 330			
 331			
 332			// set data table actions... look first for item_actions set in the fuel_modules
 333			$delete_func = '
 334			$CI =& get_instance();
 335			$link = "";';
 336			if ($has_delete_permission)
 337			{
 338				$delete_func .= 'if (isset($cols[$CI->model->key_field()]))
 339				{
 340					$url = fuel_url("'.$this->module_uri.'/delete/".$cols[$CI->model->key_field()]);
 341					$link = "<a href=\"".$url."\" class=\"action_delete\">".lang("table_action_delete")."</a>";
 342					$link .= " <input type=\"checkbox\" name=\"delete[".$cols[$CI->model->key_field()]."]\" value=\"1\" id=\"delete_".$cols[$CI->model->key_field()]."\" class=\"multi_delete\"/>";
 343				}';				
 344			}
 345
 346			$delete_func .= 'return $link;';
 347			
 348			$delete_func = create_function('$cols', $delete_func);
 349			
 350			foreach($this->table_actions as $key => $val)
 351			{
 352				if (!is_int($key)) 
 353				{
 354					$action_type = 'url';
 355					$action_val = $this->table_actions[$key];
 356					$attrs = array();
 357					if (is_array($val))
 358					{
 359						if (isset($val['url']))
 360						{
 361							$action_type = 'url';
 362							$action_val = $val['url'];
 363							if (isset($val['attrs']))
 364							{
 365								$attrs = $val['attrs'];
 366							}
 367						}
 368						else
 369						{
 370							$action_type = key($val);
 371							$action_val = current($val);
 372						}
 373						$attrs = (isset($val['attrs'])) ? $val['attrs'] : array();
 374					}
 375					$this->data_table->add_action($key, $action_val, $action_type, $attrs);
 376				}
 377				else if (strtoupper($val) == 'EDIT')
 378				{
 379					if ($this->fuel->auth->has_permission($this->permission, "edit"))
 380					{
 381						$action_url = fuel_url($this->module_uri.'/edit/{'.$this->model->key_field().'}');
 382						$this->data_table->add_action(lang('table_action_edit'), $action_url, 'url');
 383					}
 384				}
 385				else if (strtoupper($val) == 'DELETE')
 386				{
 387					$this->data_table->add_action($val, $delete_func, 'func');
 388				}
 389				else
 390				{
 391					if (strtoupper($val) != 'VIEW' OR (!empty($this->preview_path) AND strtoupper($val) == 'VIEW'))
 392					{
 393						$action_name = lang('table_action_'.strtolower($val));
 394						if (empty($action_name)) $action_name = $val;
 395						$action_url = fuel_url($this->module_uri.'/'.strtolower($val).'/{'.$this->model->key_field().'}');
 396						$this->data_table->add_action($action_name, $action_url, 'url');
 397					}
 398				}
 399			}
 400			
 401			
 402			if (!$this->rows_selectable)
 403			{
 404				$this->data_table->id = 'data_table_noselect';
 405				$this->data_table->row_action = FALSE;
 406			}
 407			else
 408			{
 409				$this->data_table->row_action = TRUE;
 410			}
 411			$this->data_table->row_alt_class = 'alt';
 412			$this->data_table->only_data_fields = array($this->model->key_field());
 413
 414			// Key and boolean fields are data only
 415//			$this->data_table->only_data_fields = array_merge(array($this->model->key_field()), $this->model->boolean_fields);
 416
 417			$this->data_table->auto_sort = TRUE;
 418			$this->data_table->actions_field = 'last';
 419			$this->data_table->no_data_str = lang('no_data');
 420			$this->data_table->lang_prefix = 'form_label_';
 421			$this->data_table->row_id_key = $this->model->key_field();
 422			
 423			$boolean_fields = $this->model->boolean_fields;
 424			if (!in_array('published', $boolean_fields)) $boolean_fields[] = 'published';
 425			if (!in_array('active', $boolean_fields)) $boolean_fields[] = 'active';
 426
 427			$has_publish_permission = ($this->fuel->auth->has_permission($this->permission, 'publish')) ? '1' : '0';
 428			$has_edit_permission = $this->fuel->auth->has_permission($this->permission, 'edit') ? '1' : '0';
 429
 430			$no = lang("form_enum_option_no");
 431			$yes = lang("form_enum_option_yes");
 432			$col_txt = lang('click_to_toggle');
 433			$key_field = $this->model->key_field();
 434
 435
 436			$_publish_toggle_callback = '
 437			$can_publish = (($heading == "published" OR $heading == "active") AND '.$has_publish_permission.' OR
 438				(($heading != "published" AND $heading != "active") AND '.$has_edit_permission.'));
 439
 440			$no = "'.$no.'";
 441			$yes = "'.$yes.'";
 442			$col_txt = "'.$col_txt.'";
 443
 444			// boolean fields
 445			if (is_null($cols[$heading]) OR $cols[$heading] == "")
 446			{
 447				return "";
 448			}
 449			else if (!is_true_val($cols[$heading]))
 450			{
 451				$text_class = ($can_publish) ? "publish_text unpublished toggle_on" : "unpublished";
 452				$action_class = ($can_publish) ? "publish_action unpublished hidden" : "unpublished hidden";
 453				return \'<span class="publish_hover"><span class="\'.$text_class.\'" id="row_published_\'.$cols["'.$key_field.'"].\'" data-field="\'.$heading.\'">\'.$no.\'</span><span class="\'.$action_class.\'">\'.$col_txt.\'</span></span>\';
 454			}
 455			else
 456			{
 457				$text_class = ($can_publish) ? "publish_text published toggle_off" : "published";
 458				$action_class = ($can_publish) ? "publish_action published hidden" : "published hidden";
 459				return \'<span class="publish_hover"><span class="\'.$text_class.\'" id="row_published_\'.$cols["'.$key_field.'"].\'" data-field="\'.$heading.\'">\'.$yes.\'</span><span class="\'.$action_class.\'">\'.$col_txt.\'</span></span>\';
 460				
 461			}';
 462
 463			$_publish_toggle_callback = create_function('$cols, $heading', $_publish_toggle_callback);
 464
 465			foreach($boolean_fields as $bool)
 466			{
 467				$this->data_table->add_field_formatter($bool, $_publish_toggle_callback);
 468			}
 469			
 470			$this->data_table->auto_sort = TRUE;
 471			$heading_sort_func = (isset($this->disable_heading_sort) AND $this->disable_heading_sort) ? '' : 'fuel.sortList';
 472			$this->data_table->sort_js_func = $heading_sort_func;
 473			
 474			$this->data_table->assign_data($items, $this->table_headers);
 475
 476			$vars['table'] = $this->data_table->render();
 477			if (!empty($items[0]) AND (!empty($this->precedence_col) AND isset($items[0][$this->precedence_col])))
 478			{
 479				$vars['params']['precedence'] = 1;
 480			}
 481			$this->load->module_view(FUEL_FOLDER, '_blocks/module_list_table', $vars);
 482			return;
 483		}
 484		
 485		else
 486		{
 487			$this->load->library('form_builder');
 488			$this->js_controller_params['method'] = 'items';
 489			$this->js_controller_params['precedence_col'] = $this->precedence_col;
 490			
 491			
 492			$vars['table'] = $this->load->module_view(FUEL_FOLDER, '_blocks/module_list_table', $vars, TRUE);
 493			$vars['pagination'] = $this->pagination->create_links();
 494			
 495
 496			// for extra module 'filters'
 497			$field_values = array();
 498			foreach($this->filters as $key => $val)
 499			{
 500				$field_values[$key] = $params[$key];
 501			}
 502			
 503			$this->form_builder->question_keys = array();
 504			//$this->form_builder->hidden = (array) $this->model->key_field();
 505			$this->form_builder->label_layout = 'left';
 506			$this->form_builder->load_custom_fields(APPPATH.'config/custom_fields.php');
 507			$this->form_builder->set_validator($this->model->get_validation());
 508			$this->form_builder->submit_value = NULL;
 509			$this->form_builder->use_form_tag = FALSE;
 510			$this->form_builder->set_fields($this->filters);
 511			$this->form_builder->display_errors = FALSE;
 512			$this->form_builder->css_class = 'more_filters';
 513			if ($this->config->item('date_format'))
 514			{
 515				$this->form_builder->date_format = $this->config->item('date_format');
 516			}
 517			$this->form_builder->set_field_values($field_values);
 518
 519			if (method_exists($this->model, 'friendly_filter_info'))
 520			{
 521				$friendly_filter_info = $this->model->friendly_filter_info($field_values);
 522				if ( ! empty($friendly_filter_info)) {
 523					$vars['info'] = $friendly_filter_info;
 524				}
 525			}
 526
 527			// keycheck is already put in place by $this->form->close() in module_list layout
 528			$this->form_builder->key_check = FALSE; 
 529			$vars['more_filters'] = $this->form_builder->render_divs();
 530			$vars['actions'] = $this->load->module_view(FUEL_FOLDER, '_blocks/module_list_actions', $vars, TRUE);
 531			$vars['form_action'] = $this->module_uri.'/items';
 532			$vars['form_method'] = 'get';
 533			$vars['query_string'] = $query_str;
 534			$vars['description'] = $this->description;
 535			$crumbs = array($this->module_uri => $this->module_name);
 536			$this->fuel->admin->set_titlebar($crumbs);
 537			
 538			$inline = $this->input->get('inline', TRUE);
 539			$this->fuel->admin->set_inline($inline);
 540			
 541			if ($inline === TRUE)
 542			{
 543				$this->fuel->admin->set_display_mode(Fuel_admin::DISPLAY_COMPACT_TITLEBAR);
 544			}
 545			$this->fuel->admin->render($this->views['list'], $vars);
 546		}
 547	}
 548	
 549	// --------------------------------------------------------------------
 550	
 551	/**
 552	 * Displays the list (table) view but inline without the left menu
 553	 *
 554	 * @access	public
 555	 * @return	void
 556	 */	
 557	function inline_items()
 558	{
 559		$this->items(TRUE);
 560	}
 561
 562	// --------------------------------------------------------------------
 563	
 564	/**
 565	 * Processes the list view filters and returns an array of parameters
 566	 *
 567	 * @access	protected
 568	 * @return	array
 569	 */	
 570	protected function _list_process()
 571	{
 572		$this->load->library('pagination');
 573		$this->load->helper('convert');
 574		$this->load->helper('cookie');
 575
 576		/* PROCESS PARAMS BEGIN */
 577		$filters = array();
 578		
 579		$page_state = $this->fuel->admin->get_page_state($this->module_uri);
 580		unset($page_state['offset']);
 581		
 582		$defaults = array();
 583		$defaults['col'] = (!empty($this->default_col)) ? $this->default_col : $this->display_field;
 584		$defaults['order'] = (!empty($this->default_order)) ? $this->default_order : 'asc';
 585		$defaults['offset'] = 0;
 586		$defaults['limit'] = key($this->limit_options);
 587		$defaults['search_term'] = '';
 588		$defaults['view_type'] = 'list';
 589		$defaults['extra_filters'] = array();
 590		$defaults['precedence'] = 0;
 591
 592		//$defaults['language'] = '';
 593		
 594		// custom module filters defaults
 595		foreach($this->filters as $key => $val)
 596		{
 597			$defaults[$key] = (isset($val['default'])) ? $val['default'] : NULL;
 598		}
 599		
 600		$posted = array();
 601		if (!empty($_POST) OR !empty($_GET))
 602		{
 603
 604			$posted['search_term'] = $this->input->get_post('search_term', TRUE);
 605			$posted_vars = array('col', 'order', 'limit', 'offset', 'precedence', 'view_type');
 606			foreach($posted_vars as $val)
 607			{
 608				if ($this->input->get_post($val)) $posted[$val] = $this->input->get_post($val, TRUE);
 609			}
 610			
 611			// custom module filters
 612			$extra_filters = array();
 613			
 614			foreach($this->filters as $key => $val)
 615			{
 616
 617				if (isset($_POST[$key]) OR isset($_GET[$key]))
 618				{
 619					$posted[$key] = $this->input->get_post($key, TRUE);
 620
 621					// get the raw key without the comparison operators that the model uses
 622					$raw_key = preg_replace(array('#_from$#', '#_fromequal$#', '#_to$#', '#_toequal$#', '#_equal$#'), '', $key);
 623
 624					// manipulate the value if it's a date time field
 625					if (method_exists($this->model, 'field_type'))
 626					{
 627						$field_type = $this->model->field_type($raw_key);
 628						if (is_date_format($posted[$key]) AND $field_type == 'datetime' OR $field_type == 'date')
 629						{
 630							$date  = ($this->input->get_post($key) AND is_date_format($this->input->get_post($key))) ? current(explode(" ", $this->input->get_post($key))) : "";
 631							$hr    = ($this->input->get_post($key.'_hour') AND (int)$this->input->get_post($key.'_hour') > 0 AND (int)$this->input->get_post($key.'_hour') < 24) ? $this->input->get_post($key.'_hour') : "";
 632							$min   = ($this->input->get_post($key.'_min') AND is_numeric($this->input->get_post($key.'_min')))  ? $this->input->get_post($key.'_min') : "00";
 633							$ampm  = ($this->input->get_post($key.'_am_pm') AND $hr AND $min) ? $this->input->get_post($key.'_am_pm') : "";
 634							if (!empty($ampm) AND !empty($hr) AND $hr > 12)
 635							{
 636								if ($hr > 24) 
 637								{
 638									$hr = "00";
 639								}
 640								else
 641								{
 642									$hr = (int) $hr - 12;
 643									$ampm = "pm";
 644								}
 645							}
 646							$posted[$key] = $date;
 647							if (!empty($hr)) $posted[$key] .= " ".$hr.":".$min.$ampm;
 648							$posted[$key] = date('Y-m-d H:i:s', strtotime($posted[$key]));
 649						}
 650					}
 651
 652					$this->filters[$key]['value'] = $posted[$key];
 653					$extra_filters[$key] = $posted[$key];
 654
 655					
 656				}
 657			}
 658
 659			$posted['extra_filters'] = $extra_filters;
 660		}
 661		$params = array_merge($defaults, $page_state, $posted);
 662		//$params = array_merge($defaults, $uri_params, $posted);
 663		
 664		if ($params['search_term'] == lang('label_search')) $params['search_term'] = NULL;
 665		/* PROCESS PARAMS END */
 666		return $params;
 667	}
 668	
 669	// --------------------------------------------------------------------
 670	
 671	/**
 672	 * Displays the tree view
 673	 *
 674	 * @access	public
 675	 * @return	void
 676	 */	
 677	function items_tree()
 678	{
 679		// tree
 680		if (method_exists($this->model, 'tree') AND is_ajax())
 681		{
 682			$params = $this->_list_process();
 683			
 684			$this->load->library('menu');
 685			$this->menu->depth = NULL; // as deep as it goes
 686			$this->menu->use_titles = FALSE;
 687			$this->menu->root_value = 0;
 688			$this->model->add_filters($params['extra_filters']);
 689			$menu_items = $this->model->tree();
 690			
 691			if (!empty($menu_items))
 692			{
 693				$output = $this->menu->render($menu_items);
 694			}
 695			else
 696			{
 697				$output = '<div>'.lang('no_data').'</div>';
 698			}
 699			$this->output->set_output($output);
 700		}
 701		
 702	}
 703	
 704	// --------------------------------------------------------------------
 705	
 706	/**
 707	 * Saves the precedence of fields
 708	 *
 709	 * @access	public
 710	 * @return	void
 711	 */	
 712	function items_precedence()
 713	{
 714		if (is_ajax() AND !empty($_POST['data_table']) AND !empty($this->precedence_col))
 715		{
 716			if (is_array($_POST['data_table']))
 717			{
 718				$i = 0;
 719				foreach($_POST['data_table'] as $row)
 720				{
 721					if (!empty($row))
 722					{
 723						$values = array($this->precedence_col => $i);
 724						$where = array($this->model->key_field() => $row);
 725						$this->model->update($values, $where);
 726					}
 727					$i++;
 728				}
 729				
 730				// clear cache
 731				$this->_clear_cache();
 732			}
 733		}
 734	}
 735
 736	// --------------------------------------------------------------------
 737	
 738	/**
 739	 * Displays the fields to create a record (form view)
 740	 *
 741	 * @access	public
 742	 * @param	string	The name of a field, or fields spearated by colon to display in the form (optional)
 743	 * @param	string	Determines whether to redirect the page after save or not
 744	 * @return	void
 745	 */	
 746	function create($field = NULL, $redirect = TRUE)
 747	{
 748		$id = NULL;
 749		
 750		// check that the action even exists and if not, show a 404
 751		if (!$this->fuel->auth->module_has_action('save'))
 752		{
 753			show_404();
 754		}
 755		
 756		// check permissions
 757		if (!$this->fuel->auth->has_permission($this->module_obj->permission, 'create'))
 758		{
 759			show_error(lang('error_no_permissions'));
 760		}
 761		
 762		$inline = $this->fuel->admin->is_inline();
 763		
 764		if (isset($_POST[$this->model->key_field()])) // check for dupes
 765		{
 766			if ($id = $this->_process_create() AND !has_errors())
 767			{
 768				if ($inline === TRUE)
 769				{
 770					$url = fuel_uri($this->module_uri.'/inline_edit/'.$id);
 771				}
 772				else
 773				{
 774					$url = fuel_uri($this->module_uri.'/edit/'.$id);
 775				}
 776
 777				// save any tab states
 778				$this->_save_tab_state($id);
 779
 780				if ($redirect)
 781				{
 782					if (!$this->fuel->admin->has_notification(Fuel_admin::NOTIFICATION_SUCCESS))
 783					{
 784						$this->fuel->admin->set_notification(lang('data_saved'), Fuel_admin::NOTIFICATION_SUCCESS);
 785					}
 786					redirect($url);
 787				}
 788			}
 789		}
 790		
 791		$shell_vars = $this->_shell_vars($id);
 792		
 793		$passed_init_vars = ($this->input->get(NULL, TRUE)) ? $this->input->get(NULL, TRUE) : array();
 794		$form_vars = $this->_form_vars($id, $passed_init_vars, FALSE, $inline);
 795		$vars = array_merge($shell_vars, $form_vars);
 796		$vars['action'] = 'create';
 797		
 798		$crumbs = array($this->module_uri => $this->module_name, lang('action_create'));
 799		$this->fuel->admin->set_titlebar($crumbs);
 800		$this->fuel->admin->set_inline($inline);
 801		
 802		if ($inline === TRUE)
 803		{
 804			$this->fuel->admin->set_display_mode(Fuel_admin::DISPLAY_COMPACT);
 805		}
 806
 807		$vars['actions'] = $this->load->module_view(FUEL_FOLDER, '_blocks/module_inline_actions', $vars, TRUE);
 808		$this->fuel->admin->render($this->views['create_edit'], $vars);
 809		return $id;
 810	}
 811	
 812	// --------------------------------------------------------------------
 813	
 814	/**
 815	 * The same as the create method but does not show the left menu
 816	 *
 817	 * @access	public
 818	 * @param	string	The name of a field, or fields spearated by colon to display in the form (optional)
 819	 * @param	string	Determines whether to redirect the page after save or not
 820	 * @return	void
 821	 */	
 822	function inline_create($field = NULL)
 823	{
 824		$this->fuel->admin->set_inline(TRUE);
 825		$this->create($field);
 826	}
 827	
 828	// --------------------------------------------------------------------
 829	
 830	/**
 831	 * Duplicates a record. Similar to edit but without the record ID attached.
 832	 *
 833	 * @access	public
 834	 * @return	void
 835	 */	
 836	function duplicate()
 837	{
 838		$_POST[$this->model->key_field()] = 'dup';
 839		$this->create();
 840	}
 841
 842	protected function _process_create()
 843	{
 844		// reset dup id
 845		if ($_POST[$this->model->key_field()] == 'dup')
 846		{
 847			$_POST[$this->model->key_field()] = '';
 848
 849			// alter duplicate information if there is a hook
 850			$_POST = $this->model->on_duplicate($_POST);
 851
 852			$this->load->library('form_builder');
 853			$fb = new Form_builder();
 854			$fb->load_custom_fields(APPPATH.'config/custom_fields.php');
 855			$fields = $this->model->form_fields($_POST);
 856			$fb->set_fields($fields);
 857			$fb->post_process_field_values();// manipulates the $_POST values directly
 858
 859		}
 860		else
 861		{
 862			$this->model->on_before_post($this->input->post());
 863
 864			$posted = $this->_process();
 865			// set publish status to no if you do not have the ability to publish
 866			if (!$this->fuel->auth->has_permission($this->permission, 'publish'))
 867			{
 868				$posted['published'] = 'no';
 869				$posted['active'] = 'no';
 870			}
 871			$model = $this->model;
 872
 873			// run before_create hook
 874			$this->_run_hook('before_create', $posted);
 875
 876			// run before_save hook
 877			$this->_run_hook('before_save', $posted);
 878			
 879			// save the data
 880			$id = $this->model->save($posted);
 881			if (empty($id))
 882			{
 883				add_error(lang('error_invalid_id'));
 884				return FALSE;
 885			}
 886			
 887			// add id value to the posted array
 888			if (!is_array($this->model->key_field()))
 889			{
 890				$posted[$this->model->key_field()] = $id;
 891			}
 892
 893			// process $_FILES
 894			if (!$this->_process_uploads($posted))
 895			{
 896				return FALSE;
 897			}
 898			
 899			$this->model->on_after_post($posted);
 900			
 901
 902			if (!$this->model->is_valid())
 903			{
 904				add_errors($this->model->get_errors());
 905			}
 906			else
 907			{
 908				// archive data
 909				$archive_data = $this->model->cleaned_data();
 910				$archive_data[$this->model->key_field()] = $id;
 911				if ($this->archivable) $this->model->archive($id, $archive_data);
 912				$data = $this->model->find_one_array(array($this->model->table_name().'.'.$this->model->key_field() => $id));
 913
 914				// run after_create hook
 915				$this->_run_hook('after_create', $data);
 916				
 917				// run after_save hook
 918				$this->_run_hook('after_save', $data);
 919
 920				if (!empty($data))
 921				{
 922					$msg = lang('module_edited', $this->module_name, $data[$this->display_field]);
 923					$this->fuel->logs->write($msg);
 924					$this->_clear_cache();
 925					return $id;
 926				}
 927			}
 928		}
 929	}
 930	
 931	// --------------------------------------------------------------------
 932	
 933	/**
 934	 * Displays the fields to edit a record (form view)
 935	 *
 936	 * @access	public
 937	 * @param	int		The ID value of the record to edit
 938	 * @param	string	The name of a field, or fields spearated by colon to display in the form (optional)
 939	 * @param	string	Determines whether to redirect the page after save or not
 940	 * @return	void
 941	 */	
 942	function edit($id = NULL, $field = NULL, $redirect = TRUE)
 943	{
 944		// check that the action even exists and if not, show a 404
 945		if (!$this->fuel->auth->module_has_action('save') AND  $this->displayonly === FALSE)
 946		{
 947			show_404();
 948		}
 949
 950		// check permissions
 951		if (!$this->fuel->auth->has_permission($this->module_obj->permission, 'edit') AND !$this->fuel->auth->has_permission($this->module_obj->permission, 'create'))
 952		{
 953			show_error(lang('error_no_permissions'));
 954		}
 955
 956		$inline = $this->fuel->admin->is_inline();
 957		
 958		if ($this->input->post($this->model->key_field()))
 959		{
 960			if ($this->_process_edit($id) AND !has_errors())
 961			{
 962				if ($inline === TRUE)
 963				{
 964					$url = fuel_uri($this->module_uri.'/inline_edit/'.$id.'/'.$field);
 965				}
 966				else
 967				{
 968					$url = fuel_uri($this->module_uri.'/edit/'.$id.'/'.$field);
 969				}
 970				
 971				if ($redirect)
 972				{
 973					if (!$this->fuel->admin->has_notification(Fuel_admin::NOTIFICATION_SUCCESS))
 974					{
 975						$this->fuel->admin->set_notification(lang('data_saved'), Fuel_admin::NOTIFICATION_SUCCESS);
 976					}
 977					redirect($url);
 978				}
 979			}
 980		}
 981		
 982		//$vars = $this->_form($id);
 983		$data = $this->_saved_data($id);
 984		$action = (!empty($data[$this->model->key_field()])) ? 'edit' : 'create';
 985	
 986		// substitute data values into preview path
 987		$this->preview_path = $this->module_obj->url($data);
 988
 989		$shell_vars = $this->_shell_vars($id, $action);
 990		$form_vars = $this->_form_vars($id, $data, $field, $inline);
 991		
 992		$vars = array_merge($shell_vars, $form_vars);
 993		$vars['data'] = $data;
 994		$vars['action'] = $action;
 995		$vars['related_items'] = $this->model->related_items($data);
 996		
 997		
 998		// active or publish fields
 999		if (isset($data['published']))
1000		{
1001			$vars['publish'] = (!empty($data['published']) AND is_true_val($data['published'])) ? 'unpublish' : 'publish';
1002		}
1003		
1004		if (isset($data['active']))
1005		{
1006			$vars['activate'] = (!empty($data['active']) AND is_true_val($data['active'])) ? 'deactivate' : 'activate';
1007		}
1008		
1009		if (!empty($field))
1010		{
1011			$this->fuel->admin->set_display_mode(Fuel_admin::DISPLAY_COMPACT_NO_ACTION);
1012		}
1013		else if ($inline === TRUE)
1014		{
1015			$this->fuel->admin->set_display_mode(Fuel_admin::DISPLAY_COMPACT);
1016		}
1017
1018		$crumbs = array($this->module_uri => $this->module_name);
1019		if (!empty($data[$this->display_field]))
1020		{
1021			$crumbs[''] = character_limiter(strip_tags($data[$this->display_field]), 50);
1022		}
1023		
1024		$this->fuel->admin->set_titlebar($crumbs);
1025
1026		$vars['actions'] = $this->load->module_view(FUEL_FOLDER, '_blocks/module_create_edit_actions', $vars, TRUE);
1027		$this->fuel->admin->render($this->views['create_edit'], $vars);
1028
1029		// do this after rendering so it doesn't render current page'
1030		if (!empty($data[$this->display_field]) AND $inline !== TRUE)
1031		{
1032			$this->fuel->admin->add_recent_page($this->uri->uri_string(), $this->module_name.': '.$data[$this->display_field], $this->module);
1033		}
1034		
1035	}
1036	
1037	// --------------------------------------------------------------------
1038	
1039	/**
1040	 * The same as the edit method but does not show the left menu
1041	 *
1042	 * @access	public
1043	 * @param	int		The ID value of the record to edit
1044	 * @param	string	The name of a field, or fields spearated by colon to display in the form (optional)
1045	 * @return	void
1046	 */	
1047	function inline_edit($id = NULL, $field = NULL)
1048	{
1049		if (empty($id))
1050		{
1051			show_404();
1052		}
1053		
1054		$this->fuel->admin->set_inline(TRUE);
1055		$this->edit($id, $field);
1056	}
1057	
1058	
1059	// --------------------------------------------------------------------
1060	
1061	/**
1062	 * Processes the form data to save
1063	 *
1064	 * @access	protected
1065	 * @param	int		The ID value of the record to edit
1066	 * @return	boolean
1067	 */	
1068	protected function _process_edit($id)
1069	{
1070		$this->model->on_before_post($this->input->post());
1071		
1072		$posted = $this->_process();
1073
1074		// run before_edit hook
1075		$this->_run_hook('before_edit', $posted);
1076		
1077		// run before_save hook
1078		$this->_run_hook('before_save', $posted);
1079
1080		if ($this->model->save($posted))
1081		{
1082			// process $_FILES...
1083			if (!$this->_process_uploads($posted))
1084			{
1085				return FALSE;
1086			}
1087			
1088			$this->model->on_after_post($posted);
1089			
1090			if (!$this->model->is_valid())
1091			{
1092				add_errors($this->model->get_errors());
1093			}
1094			else
1095			{
1096				// archive data
1097				$archive_data = $this->model->cleaned_data();
1098				if ($this->archivable) $this->model->archive($id, $archive_data);
1099				$data = $this->model->find_one_array(array($this->model->table_name().'.'.$this->model->key_field() => $id));
1100				
1101				// run after_edit hook
1102				$this->_run_hook('after_edit', $data);
1103
1104				// run after_save hook
1105				$this->_run_hook('after_save', $data);
1106
1107				$msg = lang('module_edited', $this->module_name, $data[$this->display_field]);
1108				$this->fuel->logs->write($msg);
1109				$this->_clear_cache();
1110				return TRUE;
1111			}
1112		}
1113		return FALSE;
1114	}
1115	
1116	// --------------------------------------------------------------------
1117	
1118	/**
1119	 * Sanitizes the input based on the module's settings
1120	 *
1121	 * @access	protected
1122	 * @param	array	The array of posted data to sanitize
1123	 * @return	array
1124	 */	
1125	protected function _sanitize($data)
1126	{
1127		$posted = $data;
1128		
1129		if (!empty($this->sanitize_input))
1130		{
1131			// functions that are valid for sanitizing
1132			$valid_funcs = $this->fuel->config('module_sanitize_funcs');
1133			
1134			if ($this->sanitize_input === TRUE)
1135			{
1136				foreach($data as $key => $val)
1137				{
1138					if (!empty($val))
1139					{
1140						$posted[$key] = xss_clean($val);	
1141					}
1142					
1143				}
1144			}
1145			else
1146			{
1147				// force to array to normalize
1148				$sanitize_input = (array) $this->sanitize_input;
1149				
1150				if (is_array($data))
1151				{
1152					foreach($data as $key => $post)
1153					{
1154						if (is_array($post))
1155						{
1156							$posted[$key] = $this->_sanitize($data[$key]);
1157						}
1158						else
1159						{
1160							// loop through sanitzation functions 
1161							foreach($sanitize_input as $func)
1162							{
1163								$func = (isset($valid_funcs[$func])) ? $valid_funcs[$func] : FALSE;
1164								if ($func)
1165								{
1166									$posted[$key] = $func($posted[$key]);
1167								}
1168							}
1169						}
1170					}
1171				}
1172				else
1173				{
1174					// loop through sanitzation functions 
1175					foreach($sanitize_input as $key => $val)
1176					{
1177						$func = (isset($valid_funcs[$val])) ? $valid_funcs[$val] : FALSE;
1178						if ($func)
1179						{
1180							$posted = $func($posted);
1181						}
1182					}
1183				}
1184			}
1185		}
1186
1187		return $posted;
1188	}
1189	
1190	// --------------------------------------------------------------------
1191	
1192	/**
1193	 * Returns an array of shell variables to apply to the main area of the page
1194	 *
1195	 * @access	protected
1196	 * @param	int		The ID value of the record to edit
1197	 * @param	string	The name of the action to apply to the main form element
1198	 * @return	array
1199	 */	
1200	protected function _shell_vars($id = NULL, $action = 'create')
1201	{
1202		$model = $this->model;
1203		$this->js_controller_params['method'] = 'add_edit';
1204		$this->js_controller_params['linked_fields'] = $this->model->linked_fields;
1205		
1206		// other variables
1207		$vars['id'] = $id;
1208		$vars['versions'] = ($this->displayonly === FALSE) ? $this->fuel_archives_model->options_list($id, $this->model->table_name()) : array();
1209		$vars['others'] = $this->model->get_others($this->display_field, $id);
1210		$vars['action'] = $action;
1211		
1212		$vars['module'] = $this->module;
1213		$vars['notifications'] = $this->load->module_view(FUEL_FOLDER, '_blocks/notifications', $vars, TRUE);
1214		
1215		return $vars;
1216	}
1217	
1218	
1219	// --------------------------------------------------------------------
1220	
1221	/**
1222	 * Returns an array of saved data based on the id value passed
1223	 *
1224	 * @access	protected
1225	 * @param	int		The ID value of the record to edit
1226	 * @return	array
1227	 */	
1228	protected function _saved_data($id)
1229	{
1230		if (empty($id)) return array();
1231		
1232		$edit_method = $this->edit_method;
1233		if ($edit_method != 'find_one_array')
1234		{
1235			$saved = $this->model->$edit_method($id);
1236		}
1237		else
1238		{
1239			$saved = $this->model->$edit_method(array($this->model->table_name().'.'.$this->model->key_field() => $id));
1240		}
1241		return $saved;
1242	}
1243	
1244	// seperated to make it easier in subclasses to use the form without rendering the page
1245	protected function _form_vars($id = NULL, $values = array(), $field = NULL, $inline = FALSE)
1246	{
1247		$this->load->library('form_builder');
1248		
1249		// load custom fields
1250		$this->form_builder->load_custom_fields(APPPATH.'config/custom_fields.php');
1251
1252		$model = $this->model;
1253		$this->js_controller_params['method'] = 'add_edit';
1254		$action = (!empty($values[$this->model->key_field()])) ? 'edit' : 'create';
1255		
1256		// create fields... start with the table info and go from there
1257		$fields = (!empty($values)) ? $this->model->form_fields($values) : $this->model->form_fields($_POST);
1258
1259		// if field parameter is set, then we just display a single field
1260		if (!empty($field))
1261		{
1262			
1263			// added per pierlo in Forum (http://www.getfuelcms.com/forums/discussion/673/fuel_helper-fuel_edit-markers)
1264			$columns = explode(':', $field);
1265			
1266			// special case if you use the word required
1267			if (in_array('required', $columns))
1268			{
1269				$columns = array_merge($columns, $this->model->required);
1270			}
1271			
1272			// set them to hidden... just in case model hooks require the values to be passed on save
1273			foreach($fields as $k => $f)
1274			{
1275				if (!in_array($k, $columns))
1276				{
1277					$fields[$k]['type'] = 'hidden';
1278				}
1279				
1280				if (count($columns) <= 1)
1281				{
1282					$fields[$k]['display_label'] = FALSE;
1283					$fields[$k]['required'] = FALSE;
1284				}
1285			}
1286		}
1287		
1288		// set published/active to hidden since setting this is an buttton/action instead of a form field
1289		$form = '';
1290		if (is_array($fields))
1291		{
1292			
1293			$field_values = (!empty($_POST)) ? $_POST : $values;
1294			
1295			$published_active = array(
1296				'publish' => 'published',
1297				'active' => 'activate'
1298			);
1299			foreach($published_active as $k => $v)
1300			{
1301				if (!$this->fuel->auth->has_permission($this->permission, $k))
1302				{
1303					unset($fields[$v]);
1304				}
1305
1306				if (isset($fields[$v]) AND !empty($values[$v]))
1307				{
1308					$fields['published']['value'] = $values[$v];
1309				}
1310			}
1311
1312			$this->form_builder->set_validator($this->model->get_validation());
1313
1314			// add hidden field with the module name for convenience
1315			$common_fields = $this->_common_fields($field_values);
1316			$fields = array_merge($fields, $common_fields);
1317
1318			$fields['__fuel_inline_action__'] = array('type' => 'hidden');
1319			$fields['__fuel_inline_action__']['class'] = '__fuel_inline_action__';
1320			$fields['__fuel_inline_action__']['value'] = (empty($id)) ? 'create' : 'edit';
1321			
1322			$fields['__fuel_inline__'] = array('type' => 'hidden');
1323			$fields['__fuel_inline__']['value'] = ($inline) ? 1 : 0;
1324
1325			$this->form_builder->submit_value = lang('btn_save');
1326			$this->form_builder->question_keys = array();
1327			$this->form_builder->use_form_tag = FALSE;
1328			$this->form_builder->hidden = (array) $this->model->key_field();
1329			$this->form_builder->set_fields($fields);
1330			$this->form_builder->display_errors = FALSE;
1331			$this->form_builder->set_field_values($field_values);
1332
1333			if ($this->config->item('date_format'))
1334			{
1335				$this->form_builder->date_format = $this->config->item('date_format');
1336			}
1337
1338			if ($inline)
1339			{
1340				$this->form_builder->cancel_value = lang('viewpage_close');
1341			}
1342			else
1343			{
1344				$this->form_builder->cancel_value = lang('btn_cancel');
1345			}
1346
1347			// we will set this in the BaseFuelController.js file so that the jqx page variable is available upon execution of any form field js
1348			//$this->form_builder->auto_execute_js = FALSE;
1349			if (!isset($fields['__FORM_BUILDER__'], $fields['__FORM_BUILDER__']['displayonly']))
1350			{
1351				$this->form_builder->displayonly = $this->displayonly;
1352			}
1353			
1354			
1355			$form = $this->form_builder->render();
1356		}
1357		$action_uri = $action.'/'.$id.'/'.$field;
1358		$vars['form_action'] = ($inline) ? $this->module_uri.'/inline_'.$action_uri : $this->module_uri.'/'.$action_uri;
1359		$vars['form'] = $form;
1360		$vars['data'] = $values;
1361		$vars['error'] = $this->model->get_errors();
1362		$vars['notifications'] = $this->load->module_view(FUEL_FOLDER, '_blocks/notifications', $vars, TRUE);
1363		$vars['instructions'] = (empty($field)) ? $this->instructions : '';
1364		$vars['field'] = (!empty($field));
1365		return $vars;
1366	}
1367
1368	protected function _process()
1369	{
1370		$this->load->helper('security');
1371
1372		$this->_orig_post = $_POST;
1373
1374		// filter placeholder $_POST values 
1375		$callback = create_function('$matches', '
1376			if (isset($_POST[$matches["2"]]))
1377			{
1378				$str = $matches[1].$_POST[$matches["2"]].$matches[3];
1379			}
1380			else
1381			{
1382				$str = $matches[0];
1383			}
1384			return $str;
1385		');
1386		
1387		// first loop through and create simple non-namespaced $_POST values if they don't exist for convenience'
1388		foreach($_POST as $key => $val)
1389		{
1390			$tmp_key = end(explode('--', $key));
1391			$_POST[$tmp_key] = $val;
1392		}
1393
1394		// now loop through and do any substitution
1395		foreach($_POST as $key => $val)
1396		{
1397			if (is_string($val))
1398			{
1399				$_POST[$key] = preg_replace_callback('#(.*)\{(.+)\}(.*)#U', $callback, $val);
1400			}
1401		}
1402
1403		// set boolean fields 
1404		if (!empty($this->model->boolean_fields) AND is_array($this->model->boolean_fields))
1405		{
1406			foreach($this->model->boolean_fields as $val)
1407			{
1408				$_POST[$val] = (isset($_POST[$val])) ? $_POST[$val] : 0;
1409			}
1410		}
1411
1412		// if no permission to publish, then we revoke
1413		if (!$this->fuel->auth->has_permission($this->permission, 'publish'))
1414		{
1415			unset($_POST['published']);
1416		}
1417		
1418		// set key_field if it is not id
1419		if (!empty($_POST['id']) AND $this->model->key_field() != 'id')
1420		{
1421			$_POST[$this->model->key_field()] = $_POST['id'];
1422		}
1423
1424		// run any form field post processing hooks
1425		$this->load->library('form_builder');
1426		
1427		// use a new instance to prevent problems when duplicating
1428		$fb = new Form_builder();
1429		$fb->load_custom_fields(APPPATH.'config/custom_fields.php');
1430		$fields = $this->model->form_fields($_POST);
1431		$fb->set_fields($fields);
1432		$fb->post_process_field_values();// manipulates the $_POST values directly
1433
1434		// sanitize input if set in module configuration
1435		$posted = $this->_sanitize($_POST);
1436
1437		return $posted;
1438	}
1439	
1440	function form($id = NULL, $field = NULL)
1441	{
1442		$saved = $this->_saved_data($id);
1443		$vars = $this->_form_vars($id, $saved, $field);
1444		$this->load->module_view(FUEL_FOLDER, '_layouts/module_form', $vars);
1445	}
1446
1447	function delete($id = NULL)
1448	{
1449		// check that the action even exists and if not, show a 404
1450		if (!$this->fuel->auth->module_has_action('delete'))
1451		{
1452			show_404();
1453		}
1454		
1455		if (!$this->fuel->auth->has_permission($this->permission, 'delete')) 
1456		{
1457			show_error(lang('error_no_permissions'));
1458		}
1459
1460		$inline = $this->fuel->admin->is_inline();
1461		if (!empty($_POST['id']))
1462		{
1463			$posted = explode('|', $this->input->post('id', TRUE));
1464			
1465			
1466			// run before_delete hook
1467			$this->_run_hook('before_delete', $posted);
1468			
1469			// Flags
1470			$any_success = $any_failure = FALSE;
1471			
1472			foreach ($posted as $id)
1473			{
1474				if ($this->model->delete(array($this->model->key_field() => $id)))
1475				{
1476					$any_success = TRUE;
1477					
1478				}
1479				else
1480				{
1481					$any_failure = TRUE;
1482					
1483				}
1484			}
1485			
1486			// run after_delete hook
1487			$this->_run_hook('after_delete', $posted);
1488			
1489			$this->_clear_cache();
1490			
1491			if (count($posted) > 1)
1492			{
1493				$this->fuel->logs->write(lang('module_multiple_deleted', $this->module));
1494			}
1495			else
1496			{
1497				$this->fuel->logs->write(lang('module_deleted', count($posted), $this->module));
1498			}
1499			
1500			if ($inline)
1501			{
1502				$vars['title'] = '';
1503				$vars['id'] = '';
1504				$vars['back_action'] = '';
1505				$this->fuel->admin->render('modules/module_close_modal', $vars);
1506				$this->fuel->admin->set_display_mode(Fuel_admin::DISPLAY_COMPACT_TITLEBAR);
1507				$this->fuel->admin->render($this->views['delete'], $vars);
1508			}
1509			else
1510			{
1511				// set a success delete message
1512				if ($any_success)
1513				{
1514					if (!$this->session->flashdata('success'))
1515					{
1516						$this->fuel->admin->set_notification(lang('data_deleted'), Fuel_admin::NOTIFICATION_SUCCESS);
1517					}
1518				}
1519
1520				// set an error delete message
1521				if ($any_failure)
1522				{
1523					// first try to get an error added in model by $this->add_error('...')
1524					$msg = $this->model->get_validation()->get_last_error();
1525
1526					// if there is none like that, lets use default message
1527					if (is_null($msg))
1528					{
1529						$msg = lang('data_not_deleted');
1530					}
1531					$this->fuel->admin->set_notification($msg, Fuel_admin::NOTIFICATION_ERROR);
1532				}
1533				
1534				$url = fuel_uri($this->module_uri);
1535				redirect($url);
1536			}
1537		}
1538		else
1539		{
1540			$this->js_controller_params['method'] = 'deleteItem';
1541			
1542			$vars = array();
1543			if (!empty($_POST['delete']) AND is_array($_POST['delete'])) 
1544			{
1545				$data = array();
1546				foreach($this->input->post('delete') as $key => $val)
1547				{
1548					$d = $this->model->find_by_key($key, 'array');
1549					if (!empty($d)) $data[] = $d[$this->display_field];
1550				}
1551				$vars['id'] = implode('|', array_keys($_POST['delete']));
1552				$vars['title'] = implode(', ', $data);
1553			}
1554			else
1555			{
1556				$data = $this->model->find_by_key($id, 'array');
1557				$vars['id'] = $id;
1558				if (isset($data[$this->display_field]))
1559				{
1560					$vars['title'] = $data[$this->display_field];
1561				}
1562			}
1563			
1564			if (empty($data))
1565			{
1566				show_404();
1567			}
1568			
1569			$vars['error'] = $this->model->get_errors();
1570			
1571			$crumbs = array($this->module_uri => $this->module_name);
1572			$crumbs[''] = character_limiter(strip_tags(lang('action_delete').' '.$vars['title']), 50);
1573			
1574			$this->fuel->admin->set_titlebar($crumbs);
1575			
1576			if ($inline)
1577			{
1578				$this->fuel->admin->set_display_mode(Fuel_admin::DISPLAY_COMPACT_NO_ACTION);
1579				$vars['back_action'] = fuel_url($this->module_uri.'/inline_edit/'.$id);
1580			}
1581			else
1582			{
1583				$this->fuel->admin->set_display_mode(Fuel_admin::DISPLAY_NO_ACTION);
1584				$vars['back_action'] = fuel_url($this->module_uri.'/');
1585			}
1586			$action_uri = 'delete/'.$id;
1587			$vars['form_action'] = ($inline) ? $this->module_uri.'/inline_'.$action_uri : $this->module_uri.'/'.$action_uri;
1588
1589			$this->fuel->admin->render($this->views['delete'], $vars);
1590		}
1591	}
1592	
1593	function inline_delete($id)
1594	{
1595		$this->fuel->admin->set_inline(TRUE);
1596		$this->delete($id);
1597	}
1598	
1599	function restore()
1600	{
1601		if (!$this->fuel->auth->has_permission($this->permission, 'edit')) 
1602		{
1603			show_error(lang('error_no_permissions'));
1604		}
1605		
1606		if (!empty($_POST['fuel_restore_version']) AND !empty($_POST['fuel_restore_ref_id']))
1607		{
1608			if (!$this->model->restore($this->input->post('fuel_restore_ref_id'), $this->input->post('fuel_restore_version')))
1609			{
1610				$msg = lang('module_restored', $this->module_name);
1611				$this->fuel->logs->write($msg);
1612				
1613				$this->fuel->admin->set_notification($this->model->get_validation()->get_last_error(), Fuel_admin::NOTIFICATION_ERROR);
1614				
1615			}
1616			else
1617			{
1618				if (!$this->session->flashdata('success'))
1619				{
1620					$this->fuel->admin->set_notification(lang('module_restored_success'), Fuel_admin::NOTIFICATION_SUCCESS);
1621				}
1622				$this->_clear_cache();
1623			}
1624			redirect(fuel_uri($this->module_uri.'/edit/'.$this->input->post('fuel_restore_ref_id', TRUE)));
1625		}
1626		else
1627		{
1628			show_404();
1629		}
1630	}
1631	
1632	function replace($id = NULL)
1633	{
1634		if (empty($id))
1635		{
1636			show_404();
1637		}
1638		
1639		if (!$this->fuel->auth->has_permission($this->permission, 'edit') OR !$this->fuel->auth->has_permission($this->permission, 'delete')) 
1640		{
1641			show_error(lang('error_no_permissions'));
1642		}
1643		
1644		$success = FALSE;
1645		if (!empty($_POST))
1646		{
1647			if (!empty($_POST['fuel_replace_id']))
1648			{
1649				$replace_id = $this->input->post('fuel_replace_id');
1650				//$delete = is_true_val($this->input->post('fuel_delete_replacement'));
1651				$delete = TRUE;
1652				if (!$this->model->replace($replace_id, $id, $delete))
1653				{
1654					add_error($this->model->get_validation()->get_last_error());
1655				}
1656				else
1657				{
1658					$this->fuel->admin->set_notification(lang('module_replaced_success'), Fuel_admin::NOTIFICATION_SUCCESS);
1659					$success = TRUE;
1660					$this->_clear_cache();
1661				}
1662			}
1663			else
1664			{
1665				add_error(lang('error_select_replacement'));
1666			}
1667			//redirect(fuel_uri($this->module_uri.'/edit/'.$id));
1668		}
1669		$this->load->library('form_builder');
1670		
1671		$fields = array();
1672		$other_options = $this->model->get_others($this->display_field, $id);
1673		$fields['fuel_replace_id'] = array('label' => 'Replace record:', 'type' => 'select', 'options' => $other_options, 'first_option' => 'Select record to replace...', 'style' => 'max-width: 400px', 'disabled_options' => array($id));
1674		//$fields['fuel_delete_replacement'] = array('label' => 'Delete replacement', 'type' => 'checkbox', 'value' => 'yes');
1675		if ($success)
1676		{
1677			$fields['new_fuel_replace_id'] = array('type' => 'hidden', 'value' => $replace_id);
1678		}
1679		
1680		//$this->form_builder->use_form_tag = FALSE;
1681		$this->form_builder->set_fields($fields);
1682		$this->form_builder->display_errors = FALSE;
1683		//$this->form_builder->submit_value = NULL;
1684		
1685		$vars['form'] = $this->form_builder->render();
1686		$this->fuel->admin->set_inline(TRUE);
1687
1688		$crumbs = array('' => $this->module_name, lang('action_replace'));
1689		$this->fuel->admin->set_titlebar($crumbs);
1690		$this->fuel->admin->render('modules/module_replace', $vars);
1691		
1692	}
1693	
1694	// displays the module's designated view'
1695	function view($id = NULL)
1696	{
1697		if (!empty($this->preview_path) AND !empty($id))
1698		{
1699			$data = $this->model->find_one_array(array($this->model->table_name().'.'.$this->model->key_field() => $id));
1700
1701			$url = $this->module_obj->url($data);
1702
1703			// change the last page to be the referrer
1704			$last_page = (isset($_SERVER['HTTP_REFERER'])) ? substr($_SERVER['HTTP_REFERER'], strlen(site_url())) : NULL;
1705			$this->fuel->admin->set_last_page($last_page);
1706			

Large files files are truncated, but you can click here to view the full file