class-fl-builder-user-templates.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622
  1. <?php
  2. /**
  3. * User defined templates for the builder.
  4. *
  5. * @since 1.8
  6. */
  7. final class FLBuilderUserTemplates {
  8. /**
  9. * Initialize hooks.
  10. *
  11. * @since 1.8
  12. * @return void
  13. */
  14. static public function init() {
  15. /* Actions */
  16. add_action( 'plugins_loaded', __CLASS__ . '::init_ajax' );
  17. add_action( 'after_setup_theme', __CLASS__ . '::register_user_access_settings' );
  18. add_action( 'init', __CLASS__ . '::load_settings', 1 );
  19. add_action( 'wp_footer', __CLASS__ . '::render_ui_js_templates' );
  20. /* Filters */
  21. add_filter( 'template_include', __CLASS__ . '::template_include', 999 );
  22. add_filter( 'fl_builder_has_templates', __CLASS__ . '::has_templates', 10, 2 );
  23. add_filter( 'fl_builder_template_selector_data', __CLASS__ . '::selector_data', 999 );
  24. add_filter( 'fl_builder_ui_bar_buttons', __CLASS__ . '::ui_bar_buttons' );
  25. add_filter( 'fl_builder_ui_js_config', __CLASS__ . '::ui_js_config' );
  26. add_filter( 'fl_builder_settings_form_config', __CLASS__ . '::settings_form_config' );
  27. add_filter( 'fl_builder_content_classes', __CLASS__ . '::content_classes' );
  28. add_filter( 'fl_builder_render_nodes', __CLASS__ . '::render_nodes' );
  29. add_filter( 'fl_builder_row_attributes', __CLASS__ . '::row_attributes', 10, 2 );
  30. add_filter( 'fl_builder_column_attributes', __CLASS__ . '::column_attributes', 10, 2 );
  31. add_filter( 'fl_builder_module_attributes', __CLASS__ . '::module_attributes', 10, 2 );
  32. add_filter( 'fl_builder_content_panel_data', __CLASS__ . '::filter_content_panel_data' );
  33. add_filter( 'fl_builder_content_elements_data', __CLASS__ . '::filter_content_items_data' );
  34. }
  35. /**
  36. * Initialize AJAX actions.
  37. *
  38. * @since 1.8
  39. * @return void
  40. */
  41. static public function init_ajax() {
  42. FLBuilderAJAX::add_action( 'save_user_template', 'FLBuilderModel::save_user_template', array( 'settings' ) );
  43. FLBuilderAJAX::add_action( 'delete_user_template', 'FLBuilderModel::delete_user_template', array( 'template_id' ) );
  44. FLBuilderAJAX::add_action( 'save_node_template', 'FLBuilderModel::save_node_template', array( 'node_id', 'settings' ) );
  45. FLBuilderAJAX::add_action( 'delete_node_template', 'FLBuilderModel::delete_node_template', array( 'template_id' ) );
  46. }
  47. /**
  48. * Registers the user access settings for user templates.
  49. *
  50. * @since 1.10
  51. * @return void
  52. */
  53. static public function register_user_access_settings() {
  54. FLBuilderUserAccess::register_setting( 'builder_admin', array(
  55. 'default' => array( 'administrator' ),
  56. 'group' => __( 'Admin', 'vamtam-elements-b' ),
  57. 'label' => __( 'Builder Admin', 'vamtam-elements-b' ),
  58. 'description' => __( 'The selected roles will be able to access the builder admin menu.', 'vamtam-elements-b' ),
  59. 'order' => '100',
  60. ) );
  61. FLBuilderUserAccess::register_setting( 'global_node_editing', array(
  62. 'default' => 'all',
  63. 'group' => __( 'Frontend', 'vamtam-elements-b' ),
  64. 'label' => __( 'Global Rows and Modules Editing', 'vamtam-elements-b' ),
  65. 'description' => __( 'The selected roles will be able to edit global rows and modules.', 'vamtam-elements-b' ),
  66. 'order' => '10',
  67. ) );
  68. }
  69. /**
  70. * Loads files for the template settings.
  71. *
  72. * @since 1.8
  73. * @return void
  74. */
  75. static public function load_settings() {
  76. require_once VAMTAMEL_B_USER_TEMPLATES_DIR . 'includes/user-template-settings.php';
  77. require_once VAMTAMEL_B_USER_TEMPLATES_DIR . 'includes/node-template-settings.php';
  78. }
  79. /**
  80. * Trys to load page.php for editing a builder template.
  81. *
  82. * @since 1.0
  83. * @param string $template The current template to be loaded.
  84. * @return string
  85. */
  86. static public function template_include( $template ) {
  87. global $post;
  88. if ( 'string' == gettype( $template ) && $post && 'fl-builder-template' == $post->post_type ) {
  89. $page = locate_template( array( 'page.php' ) );
  90. if ( ! empty( $page ) ) {
  91. return $page;
  92. }
  93. }
  94. return $template;
  95. }
  96. /**
  97. * Hook into the fl_builder_has_templates filter and always return true
  98. * so the template selector shows even if there are no core templates
  99. * or third party theme templates available.
  100. *
  101. * @since 1.8
  102. * @param bool $has_templates
  103. * @return bool
  104. */
  105. static public function has_templates( $has_templates ) {
  106. $enabled_templates = FLBuilderModel::get_enabled_templates();
  107. if ( 'core' == $enabled_templates ) {
  108. $templates = FLBuilderModel::get_template_selector_data();
  109. return ( count( $templates['templates'] ) > 0 );
  110. } elseif ( 'user' == $enabled_templates ) {
  111. return true;
  112. } elseif ( 'enabled' == $enabled_templates ) {
  113. return true;
  114. } elseif ( 'disabled' == $enabled_templates ) {
  115. return false;
  116. }
  117. return true;
  118. }
  119. /**
  120. * Disables core or third party templates if all templates are disabled
  121. * or only user templates are enabled.
  122. *
  123. * @since 1.8
  124. * @param array $data
  125. * @return array
  126. */
  127. static public function selector_data( $data ) {
  128. if ( in_array( FLBuilderModel::get_enabled_templates(), array( 'user', 'disabled' ) ) ) {
  129. $data = array(
  130. 'templates' => array(),
  131. 'categorized' => array(),
  132. );
  133. }
  134. return $data;
  135. }
  136. /**
  137. * Modifies the UI bar buttons for user templates if needed.
  138. *
  139. * @since 1.8
  140. * @param array $buttons
  141. * @return array
  142. */
  143. static public function ui_bar_buttons( $buttons ) {
  144. $is_module_template = FLBuilderModel::is_post_user_template( 'module' );
  145. if ( isset( $buttons['content-panel'] ) && $is_module_template ) {
  146. $buttons['content-panel']['show'] = false;
  147. }
  148. return $buttons;
  149. }
  150. /**
  151. * Sets the JS config variables for user templates.
  152. *
  153. * @since 1.8
  154. * @param array $config
  155. * @return array
  156. */
  157. static public function ui_js_config( $config ) {
  158. return array_merge( $config, array(
  159. 'enabledTemplates' => FLBuilderModel::get_enabled_templates(),
  160. 'isUserTemplate' => FLBuilderModel::is_post_user_template() ? true : false,
  161. 'userCanEditGlobalTemplates' => FLBuilderUserAccess::current_user_can( 'global_node_editing' ) ? true : false,
  162. 'userTemplateType' => FLBuilderModel::get_user_template_type(),
  163. ) );
  164. }
  165. /**
  166. * Filter the data structure for the content panel.
  167. *
  168. * @since 2.0
  169. * @param array $data The existing panel data
  170. * @return array The filtered panel data
  171. */
  172. static public function filter_content_panel_data( $data ) {
  173. if ( FLBuilderModel::node_templates_enabled() ) {
  174. $saved_layouts = FLBuilderModel::get_user_templates( 'layout' );
  175. $saved_rows = FLBuilderModel::get_user_templates( 'row' );
  176. $saved_cols = FLBuilderModel::get_user_templates( 'column' );
  177. $saved_modules = FLBuilderModel::get_user_templates( 'module' );
  178. // Saved modules view
  179. $data['tabs']['modules']['views'][] = array(
  180. 'type' => 'separator',
  181. );
  182. $data['tabs']['modules']['views'][] = array(
  183. 'handle' => 'savedModules',
  184. 'name' => __( 'Saved Modules', 'vamtam-elements-b' ),
  185. 'templateName' => 'fl-content-panel-saved-modules',
  186. 'query' => array(
  187. 'kind' => 'template',
  188. 'type' => 'user',
  189. 'content' => 'module',
  190. 'categorized' => true,
  191. ),
  192. );
  193. if ( count( $saved_modules['categorized'] ) > 1 ) {
  194. foreach ( $saved_modules['categorized'] as $handle => $category ) {
  195. $data['tabs']['modules']['views'][] = array(
  196. 'handle' => 'user-' . $handle,
  197. 'name' => $category['name'],
  198. 'templateName' => 'fl-content-panel-saved-modules',
  199. 'isSubItem' => true,
  200. 'query' => array(
  201. 'kind' => 'template',
  202. 'type' => 'user',
  203. 'content' => 'module',
  204. 'category' => $handle,
  205. ),
  206. );
  207. }
  208. }
  209. $is_col_template = FLBuilderModel::is_post_user_template( 'column' );
  210. if ( ! $is_col_template ) {
  211. // Saved columns view
  212. $data['tabs']['rows']['views'][] = array(
  213. 'type' => 'separator',
  214. );
  215. $data['tabs']['rows']['views'][] = array(
  216. 'handle' => 'savedColumns',
  217. 'name' => __( 'Saved Columns', 'vamtam-elements-b' ),
  218. 'templateName' => 'fl-content-panel-saved-columns',
  219. 'query' => array(
  220. 'kind' => 'template',
  221. 'type' => 'user',
  222. 'content' => 'column',
  223. 'categorized' => true,
  224. ),
  225. );
  226. }
  227. if ( count( $saved_cols['categorized'] ) > 1 ) {
  228. foreach ( $saved_cols['categorized'] as $handle => $category ) {
  229. $data['tabs']['columns']['views'][] = array(
  230. 'handle' => 'user-' . $handle,
  231. 'name' => $category['name'],
  232. 'templateName' => 'fl-content-panel-saved-columns',
  233. 'isSubItem' => true,
  234. 'query' => array(
  235. 'kind' => 'template',
  236. 'type' => 'user',
  237. 'content' => 'column',
  238. 'category' => $handle,
  239. ),
  240. );
  241. }
  242. }
  243. $is_row_template = FLBuilderModel::is_post_user_template( 'row' );
  244. $is_module_template = FLBuilderModel::is_post_user_template( 'module' );
  245. if ( ! $is_row_template && ! $is_col_template && ! $is_module_template ) {
  246. // Saved rows view
  247. $data['tabs']['rows']['views'][] = array(
  248. 'type' => 'separator',
  249. );
  250. $data['tabs']['rows']['views'][] = array(
  251. 'handle' => 'savedRows',
  252. 'name' => __( 'Saved Rows', 'vamtam-elements-b' ),
  253. 'templateName' => 'fl-content-panel-saved-rows',
  254. 'query' => array(
  255. 'kind' => 'template',
  256. 'type' => 'user',
  257. 'content' => 'row',
  258. 'categorized' => false,
  259. ),
  260. );
  261. if ( count( $saved_rows['categorized'] ) > 1 ) {
  262. foreach ( $saved_rows['categorized'] as $handle => $category ) {
  263. $data['tabs']['rows']['views'][] = array(
  264. 'handle' => 'user-' . $handle,
  265. 'name' => $category['name'],
  266. 'templateName' => 'fl-content-panel-saved-rows',
  267. 'isSubItem' => true,
  268. 'query' => array(
  269. 'kind' => 'template',
  270. 'type' => 'user',
  271. 'content' => 'row',
  272. 'category' => $handle,
  273. ),
  274. );
  275. }
  276. }
  277. // Save templates view
  278. $data['tabs']['templates']['views'][45] = array(
  279. 'type' => 'separator',
  280. );
  281. $data['tabs']['templates']['views'][50] = array(
  282. 'handle' => 'user-templates',
  283. 'name' => __( 'Saved Templates', 'vamtam-elements-b' ),
  284. 'query' => array(
  285. 'kind' => 'template',
  286. 'type' => 'user',
  287. 'content' => 'layout',
  288. 'categorized' => true,
  289. ),
  290. 'templateName' => 'fl-content-panel-saved-templates',
  291. );
  292. if ( count( $saved_layouts['categorized'] ) > 1 ) {
  293. foreach ( $saved_layouts['categorized'] as $handle => $category ) {
  294. $data['tabs']['templates']['views'][] = array(
  295. 'handle' => 'user-' . $handle,
  296. 'name' => $category['name'],
  297. 'isSubItem' => true,
  298. 'query' => array(
  299. 'kind' => 'template',
  300. 'type' => 'user',
  301. 'content' => 'layout',
  302. 'category' => $handle,
  303. 'categorized' => false,
  304. ),
  305. 'templateName' => 'fl-content-panel-saved-templates',
  306. );
  307. }
  308. }
  309. }
  310. // Saved tab view
  311. $data['tabs']['saved'] = array(
  312. 'handle' => 'saved',
  313. 'name' => __( 'Saved', 'vamtam-elements-b' ),
  314. 'views' => array(
  315. 'main' => array(
  316. 'handle' => 'saved',
  317. 'name' => __( 'Saved', 'vamtam-elements-b' ),
  318. 'query' => array(
  319. 'kind' => 'template',
  320. 'type' => 'user',
  321. 'category' => 'uncategorized',
  322. ),
  323. ),
  324. ),
  325. );
  326. }
  327. return $data;
  328. }
  329. /**
  330. * Filter the content items js data.
  331. *
  332. * @param array $data The existing content data.
  333. * @return array The filtered data.
  334. */
  335. static public function filter_content_items_data( $data ) {
  336. $layouts = FLBuilderModel::get_user_templates( 'layout' );
  337. $layout_templates = $layouts['templates'];
  338. foreach ( $layout_templates as $template ) {
  339. $data['template'][] = $template;
  340. }
  341. $rows = FLBuilderModel::get_user_templates( 'row' );
  342. $row_templates = $rows['templates'];
  343. foreach ( $row_templates as $template ) {
  344. $data['template'][] = $template;
  345. }
  346. $cols = FLBuilderModel::get_user_templates( 'column' );
  347. $col_templates = $cols['templates'];
  348. foreach ( $col_templates as $template ) {
  349. $data['template'][] = $template;
  350. }
  351. $modules = FLBuilderModel::get_user_templates( 'module' );
  352. $module_templates = $modules['templates'];
  353. foreach ( $module_templates as $template ) {
  354. $data['template'][] = $template;
  355. }
  356. return $data;
  357. }
  358. /**
  359. * Renders the markup for the JavaScript UI templates.
  360. *
  361. * @since 1.8
  362. * @return void
  363. */
  364. static public function render_ui_js_templates() {
  365. if ( FLBuilderModel::is_builder_active() ) {
  366. include VAMTAMEL_B_USER_TEMPLATES_DIR . 'includes/ui-js-templates.php';
  367. }
  368. }
  369. /**
  370. * Modifies the config of settings forms for user templates if needed.
  371. *
  372. * @since 1.8
  373. * @param array $config
  374. * @return array
  375. */
  376. static public function settings_form_config( $config ) {
  377. $is_row = stristr( $config['class'], 'fl-builder-row-settings' );
  378. $is_col = stristr( $config['class'], 'fl-builder-col-settings' );
  379. $is_module = stristr( $config['class'], 'fl-builder-module-settings' );
  380. if ( $is_row || $is_col || $is_module ) {
  381. $post_data = FLBuilderModel::get_post_data();
  382. $global = false;
  383. if ( isset( $post_data['node_id'] ) ) {
  384. $global = FLBuilderModel::is_node_global( FLBuilderModel::get_node( $post_data['node_id'] ) );
  385. } elseif ( isset( $post_data['template_id'] ) ) {
  386. $template_post_id = FLBuilderModel::get_node_template_post_id( $post_data['template_id'] );
  387. $global = ! $template_post_id ? false : FLBuilderModel::is_post_global_node_template( $template_post_id );
  388. }
  389. if ( $global ) {
  390. $config['badges']['global'] = _x( 'Global', 'Indicator for global node templates.', 'vamtam-elements-b' );
  391. }
  392. if ( ( $is_row || $is_col || $is_module ) && ! $global && ! FLBuilderModel::is_post_node_template() && FLBuilderModel::node_templates_enabled() ) {
  393. $config['buttons'][] = 'save-as';
  394. }
  395. }
  396. return $config;
  397. }
  398. /**
  399. * Adds template classes to the builder's content classes.
  400. *
  401. * @since 1.8
  402. * @param string $classes
  403. * @return string
  404. */
  405. static public function content_classes( $classes ) {
  406. // Add template classes to the content class.
  407. if ( FLBuilderModel::is_post_user_template() ) {
  408. $classes .= ' fl-builder-template';
  409. $classes .= ' fl-builder-' . FLBuilderModel::get_user_template_type() . '-template';
  410. }
  411. // Add the global templates locked class.
  412. if ( ! FLBuilderUserAccess::current_user_can( 'global_node_editing' ) ) {
  413. $classes .= ' fl-builder-global-templates-locked';
  414. }
  415. return $classes;
  416. }
  417. /**
  418. * Short circuits node rendering and renders modules if this
  419. * is a module template.
  420. *
  421. * @since 1.8
  422. * @param bool $render
  423. * @return bool
  424. */
  425. static public function render_nodes( $render ) {
  426. if ( FLBuilderModel::is_post_user_template( 'module' ) ) {
  427. FLBuilder::render_modules();
  428. return false;
  429. } elseif ( FLBuilderModel::is_post_user_template( 'column' ) ) {
  430. $root_node = FLBuilderModel::get_node_template_root( 'column' );
  431. // Renders the column root node.
  432. if ( $root_node ) {
  433. FLBuilder::render_column( $root_node );
  434. return false;
  435. }
  436. }
  437. return $render;
  438. }
  439. /**
  440. * Adds template specific attributes for rows.
  441. *
  442. * @since 1.8
  443. * @param array $attrs
  444. * @param object $row
  445. * @return array
  446. */
  447. static public function row_attributes( $attrs, $row ) {
  448. $global = FLBuilderModel::is_node_global( $row );
  449. $active = FLBuilderModel::is_builder_active();
  450. if ( $global && $active ) {
  451. $attrs['class'][] = 'fl-node-global';
  452. }
  453. if ( $global && $active ) {
  454. $attrs['data-template'] = $row->template_id;
  455. $attrs['data-template-node'] = $row->template_node_id;
  456. $attrs['data-template-url'] = FLBuilderModel::get_node_template_edit_url( $row->template_id );
  457. }
  458. return $attrs;
  459. }
  460. /**
  461. * Adds template specific attributes for columns.
  462. *
  463. * @since 1.8
  464. * @param array $attrs
  465. * @param object $col
  466. * @return array
  467. */
  468. static public function column_attributes( $attrs, $col ) {
  469. $global = FLBuilderModel::is_node_global( $col );
  470. $active = FLBuilderModel::is_builder_active();
  471. if ( $global && $active ) {
  472. $attrs['class'][] = 'fl-node-global';
  473. }
  474. if ( $global && $active ) {
  475. $attrs['data-template'] = $col->template_id;
  476. $attrs['data-template-node'] = $col->template_node_id;
  477. if ( isset( $col->template_root_node ) ) {
  478. $attrs['data-template-url'] = FLBuilderModel::get_node_template_edit_url( $col->template_id );
  479. }
  480. }
  481. return $attrs;
  482. }
  483. /**
  484. * Adds template specific attributes for modules.
  485. *
  486. * @since 1.8
  487. * @param array $attrs
  488. * @param object $module
  489. * @return array
  490. */
  491. static public function module_attributes( $attrs, $module ) {
  492. $global = FLBuilderModel::is_node_global( $module );
  493. $active = FLBuilderModel::is_builder_active();
  494. if ( $global && $active ) {
  495. $attrs['class'][] = 'fl-node-global';
  496. }
  497. if ( $global && $active ) {
  498. $attrs['data-template'] = $module->template_id;
  499. $attrs['data-template-node'] = $module->template_node_id;
  500. }
  501. return $attrs;
  502. }
  503. /**
  504. * @since 1.8
  505. * @deprecated 2.0
  506. */
  507. static public function selector_filter_data( $data ) {
  508. _deprecated_function( __METHOD__, '2.0' );
  509. return $data;
  510. }
  511. /**
  512. * @since 1.6.3
  513. * @deprecated 2.0
  514. */
  515. static public function render_ui_panel_node_templates() {
  516. _deprecated_function( __METHOD__, '2.0' );
  517. }
  518. /**
  519. * @since 1.8
  520. * @deprecated 2.0
  521. */
  522. static public function render_selector_content() {
  523. _deprecated_function( __METHOD__, '2.0' );
  524. }
  525. /**
  526. * @since 1.0
  527. * @deprecated 2.0
  528. */
  529. static public function render_settings() {
  530. _deprecated_function( __METHOD__, '2.0' );
  531. }
  532. /**
  533. * @since 1.6.3
  534. * @deprecated 2.0
  535. */
  536. static public function render_node_settings( $node_id = null ) {
  537. _deprecated_function( __METHOD__, '2.0' );
  538. }
  539. }
  540. FLBuilderUserTemplates::init();