PageRenderTime 42ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/system/cms/modules/themes/controllers/admin.php

https://github.com/JamieLomas/pyrocms
PHP | 460 lines | 308 code | 67 blank | 85 comment | 34 complexity | 0d21ab75b0dd6b9737ea3c652367022a MD5 | raw file
  1. <?php defined('BASEPATH') OR exit('No direct script access allowed');
  2. /**
  3. * Admin controller for the themes module
  4. *
  5. * @author Phil Sturgeon - PyroCMS Dev Team
  6. * @author Jerel Unruh - PyroCMS Development Team
  7. * @package PyroCMS
  8. * @subpackage Themes module
  9. * @category Modules
  10. */
  11. class Admin extends Admin_Controller
  12. {
  13. /**
  14. * Validation array
  15. * @access private
  16. * @var array
  17. */
  18. private $validation_rules = array();
  19. /**
  20. * Constructor method
  21. *
  22. * @access public
  23. * @return void
  24. */
  25. public function __construct()
  26. {
  27. // Call the parent's constructor
  28. parent::__construct();
  29. $this->load->model('themes_m');
  30. $this->lang->load('themes');
  31. $this->load->library('form_validation');
  32. $this->template
  33. ->set_partial('shortcuts', 'admin/partials/shortcuts')
  34. ->append_metadata(css('themes.css', 'themes'))
  35. ->append_metadata(js('admin.js', 'themes'));
  36. }
  37. /**
  38. * List all themes
  39. *
  40. * @access public
  41. * @return void
  42. */
  43. public function index()
  44. {
  45. $themes = $this->themes_m->get_all();
  46. $data = array();
  47. foreach ($themes AS $theme)
  48. {
  49. if ( ! isset($theme->type) OR $theme->type != 'admin')
  50. {
  51. if ($theme->slug == $this->settings->default_theme)
  52. {
  53. $theme->is_default = TRUE;
  54. }
  55. $data['themes'][] = $theme;
  56. }
  57. }
  58. // Render the view
  59. $this->template
  60. ->title($this->module_details['name'])
  61. ->build('admin/index', $data);
  62. }
  63. /**
  64. * Save the option settings
  65. *
  66. * @param string $slug The theme slug
  67. * @access public
  68. * @return void
  69. */
  70. public function options($slug = '')
  71. {
  72. if ($this->input->post('btnAction') == 're-index')
  73. {
  74. $this->themes_m->delete_options($this->input->post('slug'));
  75. // now re-index all themes that don't have saved options
  76. if ($this->themes_m->get_all())
  77. {
  78. // Success...
  79. $data = array();
  80. $data['messages']['success'] = lang('themes.re-index_success');
  81. $message = $this->load->view('admin/partials/notices', $data, TRUE);
  82. return $this->template->build_json(array(
  83. 'status' => 'success',
  84. 'message' => $message
  85. ));
  86. }
  87. }
  88. $all_options = $this->themes_m->get_options_by(array('theme'=> $slug));
  89. $options_array = array();
  90. if ($all_options)
  91. {
  92. // Create dynamic validation rules
  93. foreach($all_options as $option)
  94. {
  95. $this->validation_rules[] = array(
  96. 'field' => $option->slug . (in_array($option->type, array('select-multiple', 'checkbox')) ? '[]' : ''),
  97. 'label' => $option->title,
  98. 'rules' => 'trim' . ($option->is_required ? '|required' : '') . '|max_length[255]'
  99. );
  100. $options_array[$option->slug] = $option->value;
  101. }
  102. // Set the validation rules
  103. $this->form_validation->set_rules($this->validation_rules);
  104. // Got valid data?
  105. if ($this->form_validation->run())
  106. {
  107. // Loop through again now we know it worked
  108. foreach($options_array as $option_slug => $stored_value)
  109. {
  110. $input_value = $this->input->post($option_slug, FALSE);
  111. if (is_array($input_value))
  112. {
  113. $input_value = implode(',', $input_value);
  114. }
  115. // Dont update if its the same value
  116. if ($input_value !== $stored_value)
  117. {
  118. $this->themes_m->update_options($option_slug, array('value' => $input_value));
  119. }
  120. }
  121. // Success...
  122. $data = array();
  123. $data['messages']['success'] = lang('themes.save_success');
  124. $message = $this->load->view('admin/partials/notices', $data, TRUE);
  125. return $this->template->build_json(array(
  126. 'status' => 'success',
  127. 'message' => $message
  128. ));
  129. }
  130. elseif (validation_errors())
  131. {
  132. $data = array();
  133. $message = $this->load->view('admin/partials/notices', $data, TRUE);
  134. return $this->template->build_json(array(
  135. 'status' => 'error',
  136. 'message' => $message
  137. ));
  138. }
  139. }
  140. $this->data->slug = $slug;
  141. $this->data->options_array = $all_options;
  142. $this->data->controller = &$this;
  143. $this->template->set_layout('modal', 'admin')
  144. ->build('admin/options', $this->data);
  145. }
  146. /**
  147. * Set the default theme to theme X
  148. *
  149. * @access public
  150. * @return void
  151. */
  152. public function set_default()
  153. {
  154. // Store the theme name
  155. $theme = $this->input->post('theme');
  156. // Set the theme
  157. if ($this->themes_m->set_default($this->input->post()))
  158. {
  159. $this->session->set_flashdata('success', sprintf(lang('themes.set_default_success'), $theme));
  160. }
  161. else
  162. {
  163. $this->session->set_flashdata('error', sprintf( lang('themes.set_default_error'), $theme));
  164. }
  165. if ($this->input->post('method') == 'admin_themes')
  166. {
  167. redirect('admin/themes/admin_themes');
  168. }
  169. redirect('admin/themes');
  170. }
  171. /**
  172. * Upload a theme to the server
  173. *
  174. * @access public
  175. * @return void
  176. */
  177. public function upload()
  178. {
  179. if ( ! $this->settings->addons_upload)
  180. {
  181. show_error('Uploading add-ons has been disabled for this site. Please contact your administrator');
  182. }
  183. if($this->input->post('btnAction') == 'upload')
  184. {
  185. $config['upload_path'] = FCPATH.UPLOAD_PATH;
  186. $config['allowed_types'] = 'zip';
  187. $config['max_size'] = '2048';
  188. $config['overwrite'] = TRUE;
  189. $this->load->library('upload', $config);
  190. if ($this->upload->do_upload())
  191. {
  192. $upload_data = $this->upload->data();
  193. // Check if we already have a dir with same name
  194. if($this->template->theme_exists($upload_data['raw_name']))
  195. {
  196. $this->session->set_flashdata('error', lang('themes.already_exists_error'));
  197. }
  198. else
  199. {
  200. // Now try to unzip
  201. $this->load->library('unzip');
  202. $this->unzip->allow(array('xml', 'html', 'css', 'js', 'png', 'gif', 'jpeg', 'jpg', 'swf', 'ico', 'txt', 'eot', 'svg', 'ttf', 'woff'));
  203. // Try and extract
  204. $this->unzip->extract($upload_data['full_path'], ADDONPATH . 'themes/' )
  205. ? $this->session->set_flashdata('success', lang('themes.upload_success'))
  206. : $this->session->set_flashdata('error', $this->unzip->error_string());
  207. }
  208. // Delete uploaded file
  209. @unlink($upload_data['full_path']);
  210. }
  211. else
  212. {
  213. $this->session->set_flashdata('error', $this->upload->display_errors());
  214. }
  215. redirect('admin/themes');
  216. }
  217. $this->template
  218. ->title($this->module_details['name'], lang('themes.upload_title'))
  219. ->build('admin/upload', $this->data);
  220. }
  221. /**
  222. * Delete an existing theme
  223. *
  224. * @access public
  225. * @param string $theme_name The name of the theme to delete
  226. * @return void
  227. */
  228. public function delete($theme_name = '')
  229. {
  230. $this->load->helper('file');
  231. $name_array = $theme_name ? array($theme_name) : $this->input->post('action_to');
  232. // Delete multiple
  233. if ( ! empty($name_array))
  234. {
  235. $deleted = 0;
  236. $to_delete = 0;
  237. foreach ($name_array as $theme_name)
  238. {
  239. $theme_name = urldecode($theme_name);
  240. $to_delete++;
  241. if($this->settings->default_theme == $theme_name)
  242. {
  243. $this->session->set_flashdata('error', lang('themes.default_delete_error'));
  244. }
  245. else
  246. {
  247. $theme_dir = ADDONPATH.'themes/'.$theme_name;
  248. if( is_really_writable($theme_dir) )
  249. {
  250. delete_files($theme_dir, TRUE);
  251. if(@rmdir($theme_dir))
  252. {
  253. $deleted++;
  254. }
  255. }
  256. else
  257. {
  258. $this->session->set_flashdata('error', sprintf(lang('themes.delete_error'), $theme_dir) );
  259. }
  260. }
  261. }
  262. if( $deleted == $to_delete)
  263. {
  264. $this->session->set_flashdata('success', sprintf(lang('themes.mass_delete_success'), $deleted, $to_delete) );
  265. }
  266. }
  267. else
  268. {
  269. $this->session->set_flashdata('error', lang('themes.delete_select_error'));
  270. }
  271. redirect('admin/themes');
  272. }
  273. /**
  274. * Form Control
  275. *
  276. * Returns the form control for the theme option
  277. *
  278. * @param object $option
  279. * @return string
  280. */
  281. public function form_control(&$option)
  282. {
  283. if ($option->options)
  284. {
  285. if (substr($option->options, 0, 5) == 'func:')
  286. {
  287. if (is_callable($func = substr($option->options, 5)))
  288. {
  289. $option->options = call_user_func($func);
  290. }
  291. else
  292. {
  293. $option->options = array('=' . lang('select.none'));
  294. }
  295. }
  296. if (is_string($option->options))
  297. {
  298. $option->options = explode('|', $option->options);
  299. }
  300. }
  301. switch ($option->type)
  302. {
  303. default:
  304. case 'text':
  305. $form_control = form_input(array(
  306. 'id' => $option->slug,
  307. 'name' => $option->slug,
  308. 'value' => $option->value,
  309. 'class' => 'text width-20'
  310. ));
  311. break;
  312. case 'textarea':
  313. $form_control = form_textarea(array(
  314. 'id' => $option->slug,
  315. 'name' => $option->slug,
  316. 'value' => $option->value,
  317. 'class' => 'width-20'
  318. ));
  319. break;
  320. case 'password':
  321. $form_control = form_password(array(
  322. 'id' => $option->slug,
  323. 'name' => $option->slug,
  324. 'value' => $option->value,
  325. 'class' => 'text width-20',
  326. 'autocomplete' => 'off',
  327. ));
  328. break;
  329. case 'select':
  330. $form_control = form_dropdown($option->slug, $this->_format_options($option->options), $option->value, 'class="width-20"');
  331. break;
  332. case 'select-multiple':
  333. $options = $this->_format_options($option->options);
  334. $size = sizeof($options) > 10 ? ' size="10"' : '';
  335. $form_control = form_multiselect($option->slug . '[]', $options, explode(',', $option->value), 'class="width-20"' . $size);
  336. break;
  337. case 'checkbox':
  338. $form_control = '';
  339. $stored_values = is_string($option->value) ? explode(',', $option->value) : $option->value;
  340. foreach ($this->_format_options($option->options) as $value => $label)
  341. {
  342. if (is_array($stored_values))
  343. {
  344. $checked = in_array($value, $stored_values);
  345. }
  346. else
  347. {
  348. $checked = FALSE;
  349. }
  350. $form_control .= '<label>';
  351. $form_control .= '' . form_checkbox(array(
  352. 'id' => $option->slug . '_' . $value,
  353. 'name' => $option->slug . '[]',
  354. 'checked' => $checked,
  355. 'value' => $value
  356. ));
  357. $form_control .= ' ' . $label . '</label>';
  358. }
  359. break;
  360. case 'radio':
  361. $form_control = '';
  362. foreach ($this->_format_options($option->options) as $value => $label)
  363. {
  364. $form_control .= '' . form_radio(array(
  365. 'id' => $option->slug,
  366. 'name' => $option->slug,
  367. 'checked' => $option->value == $value,
  368. 'value' => $value
  369. )) . ' ' . $label . '';
  370. }
  371. break;
  372. }
  373. return $form_control;
  374. }
  375. /**
  376. * Format Options
  377. *
  378. * Formats the options for a theme option into an associative array.
  379. *
  380. * @param array $options
  381. * @return array
  382. */
  383. private function _format_options($options = array())
  384. {
  385. $select_array = array();
  386. foreach ($options as $option)
  387. {
  388. list($value, $name) = explode('=', $option);
  389. $select_array[$value] = $name;
  390. }
  391. return $select_array;
  392. }
  393. }