PageRenderTime 47ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/themes/nonus/framework/shortcodes/ctShortcodeDecorator.class.php

https://github.com/alniko009/magic
PHP | 546 lines | 262 code | 96 blank | 188 comment | 33 complexity | 997071fc2e9d3546eb1051782e2d44d1 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. require_once dirname(__FILE__) . '../../form/utils_formbuilder.inc.php';
  3. /**
  4. * Decorates shortcode dialog
  5. * @author alex
  6. */
  7. class ctShortcodeDecorator {
  8. /**
  9. * @var ctShortcode
  10. */
  11. protected $shortcodes;
  12. /**
  13. * @var FormBuilder
  14. */
  15. protected $form;
  16. /**
  17. * @var string
  18. */
  19. protected $schemaFormat = '%name%';
  20. /**
  21. * Default valuess
  22. * @var array
  23. */
  24. protected $defaults = array();
  25. /**
  26. * Fields counter
  27. * @var int
  28. */
  29. protected $counter = 0;
  30. /**
  31. * Attributes to remove
  32. * @var array
  33. */
  34. protected $bannedAttributes = array();
  35. /**
  36. * Sets subsitutes
  37. * @var array
  38. */
  39. protected $substitutes = array();
  40. /**
  41. * Loaded js081/*
  42. * @var array
  43. */
  44. protected $loadedJs = array();
  45. /**
  46. * Parent shortcode
  47. * @var ctShortcode
  48. */
  49. protected $parentShortcode = null;
  50. /**
  51. * Parent default values
  52. * @var array
  53. */
  54. protected $parentDefaultValues;
  55. /**
  56. * @var string
  57. */
  58. protected $parentSchemaName = '';
  59. /**
  60. * @param ctShortcode[] $shortcodes
  61. * @param bool $withButtons
  62. * @param bool $withClone
  63. */
  64. public function __construct($shortcodes, $withButtons = false, $withClone = false) {
  65. $this->shortcodes = $shortcodes;
  66. $this->form = new FormBuilder();
  67. $this->form->withButtons = $withButtons;
  68. $this->form->clone = $withClone;
  69. }
  70. /**
  71. * Adds parent shortcode
  72. * @param $sh
  73. */
  74. public function setParentShortcode($sh) {
  75. $this->parentShortcode = $sh;
  76. }
  77. /**
  78. * Allows to setup default parent values
  79. * @param array $d
  80. */
  81. public function setParentDefaultValues($d) {
  82. $this->parentDefaultValues = $d;
  83. }
  84. /**
  85. * Allows to override default values
  86. * @param array $defaults
  87. */
  88. public function setDefaultValues($defaults) {
  89. $this->defaults = $defaults;
  90. }
  91. /**
  92. * Sets attributes to remove
  93. * @param $attr
  94. */
  95. public function setBannedAttributes($attr) {
  96. $this->bannedAttributes = $attr;
  97. }
  98. /**
  99. * Sets params subsitutes
  100. * @param arra y$substitutes
  101. */
  102. public function setInputSubstitutes($substitutes) {
  103. $this->substitutes = $substitutes;
  104. }
  105. /**
  106. * Sets decorator schema name
  107. * @param string $name
  108. * @throws Exception
  109. */
  110. public function setSchemaFormat($name) {
  111. if (strpos($name, '%name%') === false) {
  112. throw new Exception("Invalid format. Should contain %s");
  113. }
  114. $this->schemaFormat = $name;
  115. }
  116. /**
  117. * Renders widget
  118. * @return string
  119. */
  120. public function render() {
  121. if ($this->parentShortcode && $this->parentShortcode->getAttributes()) {
  122. $this->parentSchemaName = '[parent]';
  123. $this->appendShortcodeForm($this->parentShortcode, 'parent', $this->parentDefaultValues);
  124. $this->parentSchemaName = '';
  125. }
  126. foreach ($this->shortcodes as $shortcode) {
  127. //sometimes we may be in trouble
  128. $this->appendShortcodeForm($shortcode);
  129. }
  130. return (string)$this->form->toString();
  131. }
  132. /**
  133. * Normalizes attribute
  134. * @param string $name
  135. * @param array $attribute
  136. * @param $defaults
  137. * @return array
  138. */
  139. protected function normalizeAttribute($name, $attribute, $defaults) {
  140. if (!array_key_exists('type', $attribute)) {
  141. $attribute['type'] = 'input';
  142. }
  143. //maybe we should render it differently?
  144. if (isset($this->substitutes[$attribute['type']])) {
  145. $attribute['type'] = $this->substitutes[$attribute['type']];
  146. }
  147. //setup default values
  148. if (array_key_exists($name, $defaults)) {
  149. $attribute['default'] = $defaults[$name];
  150. }
  151. //multiple values?
  152. if (array_key_exists($this->counter, $defaults) && array_key_exists($name, $defaults[$this->counter])) {
  153. $attribute['default'] = $defaults[$this->counter][$name];
  154. }
  155. return $attribute;
  156. }
  157. /**
  158. * Handles shortcode form
  159. * @param ctShortcode $shortcode
  160. * @param null $containerName
  161. * @param null $defaults
  162. * @throws Exception
  163. * @return bool|string
  164. */
  165. protected function appendShortcodeForm($shortcode, $containerName = null, $defaults = null) {
  166. $containerName = $containerName ? $containerName : 'container_' . (++$this->counter);
  167. $this->form->addBreak($containerName);
  168. $attributes = array_diff_key($shortcode->getAttributes(), $this->bannedAttributes);
  169. $defaults = $defaults ? $defaults : $this->defaults;
  170. foreach ($attributes as $name => $attribute) {
  171. $attribute = $this->normalizeAttribute($name, $attribute, $defaults);
  172. //may be false
  173. if ($attribute['type'] && $attribute['type'] != 'false') {
  174. if (!method_exists($this, $attribute['type'])) {
  175. throw new Exception("Cannot handle " . $attribute['type'] . ' type');
  176. }
  177. $this->$attribute['type']($name, $attribute);
  178. }
  179. }
  180. return false;
  181. }
  182. /**
  183. * Renders info
  184. * @param $name
  185. * @param $data
  186. * @throws InvalidArgumentException
  187. * @return bool
  188. */
  189. protected function toggable($name, $data) {
  190. $name = isset($data['desc']) ? $data['desc'] : '';
  191. if (!isset($data['id'])) {
  192. throw new InvalidArgumentException("Required ID parameter unique for form for toggable");
  193. }
  194. //if we now this is end section, we add 'marker'
  195. if (!isset($data['end'])) {
  196. $this->form->addInlineJavascript("jQuery('#" . $data['id'] . "').click(function(){
  197. jQuery(this).parents('tr').nextUntil('#" . $data['id'] . "_end').toggle();
  198. }).click();");
  199. }
  200. $c = $this->getFormElementPrototype('', $data);
  201. $c->setTypeAsCustom('<a id="' . esc_attr($data['id']) . '" href="#">' . $name . '</a>');
  202. if (isset($data['end'])) {
  203. $c->setTypeAsCustom('<a id="' . esc_attr($data['id']) . '" href="#">' . $name . '</a>');
  204. }
  205. return $this->form->addFormElement($c);
  206. }
  207. /**
  208. * Adds icon
  209. * @param $name
  210. * @param $data
  211. */
  212. protected function icon($name, $data) {
  213. if (!isset($data['help']) && !isset($data['link'])) {
  214. throw new Exception("Please set link option!");
  215. }
  216. if (!isset($data['help'])) {
  217. $data['help'] = sprintf(__("View %s and enter icon name ex. glass", 'ct_theme'), '<a target="_blank" id="open_' . $name . '" href="' . $data['link'] . '">' . __('available icons', 'ct_theme') . '</a>');
  218. }
  219. $c = $this->getFormElementPrototype($name, $data);
  220. $c->addCustomTags('data-type="text"');
  221. $this->form->addFormElement($c);
  222. }
  223. /**
  224. * Adds checkbox
  225. * @param string $name
  226. * @param array $data
  227. */
  228. protected function checkbox($name, $data) {
  229. $c = $this->getFormElementPrototype($name, $data, 'true');
  230. $c->setTypeAsCheckbox(true);
  231. $c->checkbox_label = '';
  232. if (isset($data['default']) && $data['default'] == 'true') {
  233. $c->checked = true;
  234. }
  235. $c->addCustomTags('data-type="checkbox"');
  236. $this->form->addFormElement($c);
  237. }
  238. /**
  239. * Returns defaut form element
  240. * @param $name
  241. * @param $data
  242. * @return FormElement
  243. */
  244. protected function getFormElementPrototype($name, $data, $value = null) {
  245. //fixed form field name
  246. $schemaName = strtr($this->schemaFormat, array('%name%' => $name, '%counter%' => $this->counter, '%parent%' => $this->parentSchemaName));
  247. $default = isset($data['default']) ? $data['default'] : null;
  248. $value = $value !== null ? $value : null;
  249. if ($value === null) {
  250. $value = $default;
  251. }
  252. $e = new FormElement($schemaName, isset($data['label']) ? ucfirst($data['label']) : $this->labelize($name));
  253. $e->setValue($value); //setup default value
  254. $e->addCustomTags('data-default="' . ($default) . '"');
  255. $e->description = isset($data['help']) ? $data['help'] : '';
  256. return $e;
  257. }
  258. /**
  259. * Returns element by it's type
  260. * @param $type
  261. * @param $name
  262. * @param $data
  263. * @return FormElement
  264. * @throws Exception
  265. */
  266. public function getFormElementByType($type, $name, $data) {
  267. $attribute = $this->normalizeAttribute($name, $data, $this->defaults);
  268. //may be false
  269. if ($attribute['type'] && $attribute['type'] != 'false') {
  270. if (!method_exists($this, $attribute['type'])) {
  271. throw new Exception("Cannot handle " . $attribute['type'] . ' type');
  272. }
  273. $this->$attribute['type']($name, $attribute);
  274. return $this->form->getElement($name);
  275. }
  276. return null;
  277. }
  278. /**
  279. * Draws input
  280. * @param $name
  281. * @param $data
  282. */
  283. protected function input($name, $data) {
  284. $c = $this->getFormElementPrototype($name, $data);
  285. $c->addCustomTags('data-type="text"');
  286. $this->form->addFormElement($c);
  287. }
  288. /**
  289. * Draws textarea
  290. * @param $name
  291. * @param $data
  292. */
  293. protected function textarea($name, $data) {
  294. $c = $this->getFormElementPrototype($name, $data);
  295. $c->addCustomTags('data-type="textarea"');
  296. $c->setTypeAsTextArea();
  297. $this->form->addFormElement($c);
  298. }
  299. /**
  300. * Draws posts select
  301. * @param $name
  302. * @param $data
  303. */
  304. protected function posts_select($name, $data) {
  305. $args = wp_parse_args($data, array('numberposts' => '-1'));
  306. $data['choices'] = $this->fetchPostsAsOption($args);
  307. $this->select($name, $data);
  308. }
  309. /**
  310. * Multiselect posts
  311. * @param $name
  312. * @param $data
  313. */
  314. protected function posts_multiselect($name, $data) {
  315. $args = wp_parse_args($data, array('numberposts' => '-1'));
  316. $data['choices'] = $this->fetchPostsAsOption($args);
  317. $this->multiselect($name, $data);
  318. }
  319. /**
  320. * Gets posts as array
  321. * @param $args
  322. * @return array
  323. */
  324. protected function fetchPostsAsOption($args) {
  325. $posts = get_posts($args);
  326. $options = array();
  327. foreach ($posts as $post) {
  328. $options[$post->ID] = $post->post_title;
  329. }
  330. return $options;
  331. }
  332. /**
  333. * Select
  334. * @param $name
  335. * @param $data
  336. */
  337. protected function select($name, $data) {
  338. //2 options allowed
  339. $choices = isset($data['choices']) ? $data['choices'] : array();
  340. if (!$choices) {
  341. $choices = isset($data['options']) ? $data['options'] : array();
  342. }
  343. if (!$choices && isset($data['callback'])) {
  344. $choices = call_user_func($data['callback'], $name, $data);
  345. }
  346. $c = $this->getFormElementPrototype($name, $data);
  347. $c->setTypeAsComboBox($choices);
  348. $c->addCustomTags('data-type="select"');
  349. $this->form->addFormElement($c);
  350. }
  351. /**
  352. * Select
  353. * @param $name
  354. * @param $data
  355. */
  356. protected function multiselect($name, $data) {
  357. //2 options allowed
  358. $choices = isset($data['choices']) ? $data['choices'] : array();
  359. if (!$choices) {
  360. $choices = isset($data['options']) ? $data['options'] : array();
  361. }
  362. $name = strpos($name, '[]') !== false ? $name : $name . '[]';
  363. $c = $this->getFormElementPrototype($name, $data);
  364. $c->setTypeAsComboBox($choices);
  365. $c->addCustomTags('data-type="select" multiple="multiple" ');
  366. $this->form->addFormElement($c);
  367. }
  368. /**
  369. * Adds colorpicker
  370. * @param string $name
  371. * @param array $data
  372. */
  373. protected function colorpicker($name, $data) {
  374. $c = $this->getFormElementPrototype($name, $data);
  375. $c->cssclass = 'colorpicker';
  376. $def = $data['default'];
  377. $control = <<<EOF
  378. <div style="position:relative;">
  379. <input class="pickcolor" data-type="text" type="text" name="$name" value="$def" data-default="$def"/>
  380. <div class="colorpicker" style="z-index:100; position:absolute; display:none;"></div>
  381. </div>
  382. EOF;
  383. $c->setTypeAsCustom($control);
  384. $this->form->addFormElement($c);
  385. $dir = CT_THEME_LIB_DIR_URI . '/form/colorpicker';
  386. wp_enqueue_style('farbtastic');
  387. wp_enqueue_script('farbtastic');
  388. wp_register_script('theme_colorpicker', $dir . '/js/init.js', array('jquery'));
  389. wp_enqueue_script('theme_colorpicker');
  390. }
  391. /**
  392. * media library widget for image
  393. * @param $name
  394. * @param $data
  395. */
  396. protected function image($name, $data) {
  397. $c = $this->getFormElementPrototype($name, $data);
  398. $c->cssclass = 'media';
  399. $control = <<<EOF
  400. <div class="media">
  401. <input class="image_select" data-type="text" type="text" name="$name" />
  402. <input class="image_button" type="button" name="select image" value="Select" />
  403. </div>
  404. EOF;
  405. $c->setTypeAsCustom($control);
  406. $this->form->addFormElement($c);
  407. $js = <<<EOF
  408. jQuery(document).ready(function() {
  409. var currentTarget = null;
  410. jQuery('.image_button').click(function() {
  411. currentTarget = jQuery(this).prev('.image_select');
  412. tb_show('', 'media-upload.php?type=image&TB_iframe=true');
  413. return false;
  414. });
  415. window.send_to_editor = function(html) {
  416. imgurl = jQuery('<div>'+html+"</div>").find('img').attr('src');
  417. currentTarget.val(imgurl);
  418. tb_remove();
  419. }
  420. });
  421. EOF;
  422. $this->form->addInlineJavascript($js);
  423. wp_enqueue_style('thickbox');
  424. wp_enqueue_script('media-upload');
  425. wp_enqueue_script('thickbox');
  426. wp_enqueue_script('jquery');
  427. }
  428. /**
  429. * Transforms label
  430. * @param string $name
  431. * @return string
  432. */
  433. protected function labelize($name) {
  434. return ucfirst(str_replace(array('_', '-', '[]'), ' ', $name));
  435. }
  436. /**
  437. * Renders form
  438. * @return string
  439. */
  440. public function __toString() {
  441. try {
  442. return (string)$this->render();
  443. } catch (Exception $e) {
  444. if (WP_DEBUG) {
  445. return (string)$e;
  446. }
  447. return '';
  448. }
  449. }
  450. }