Нет описания

class-popmake-fields.php 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
  1. <?php
  2. // Exit if accessed directly
  3. if ( ! defined( 'ABSPATH' ) ) {
  4. exit;
  5. }
  6. /**
  7. * Class Popmake_Fields
  8. *
  9. * @deprecated 1.4 Use PUM_Fields instead.
  10. */
  11. class Popmake_Fields {
  12. /**
  13. * @var string
  14. */
  15. public $field_prefix = 'settings';
  16. /**
  17. * @var string
  18. */
  19. public $field_name_format = '{$prefix}[{$section}][{$field}]';
  20. /**
  21. * @var string
  22. */
  23. public $templ_value_format = '{$prefix}{$section}.{$field}';
  24. /**
  25. * @var array
  26. */
  27. public $fields = array();
  28. /**
  29. * @var array
  30. */
  31. public $sections = array();
  32. /**
  33. * @var array
  34. */
  35. public $args = array();
  36. /**
  37. * @var array
  38. */
  39. private static $instances = array();
  40. /**
  41. * @param array $args
  42. */
  43. public function __construct( $args = array() ) {
  44. $sections = isset( $args['sections'] ) ? $args['sections'] : array(
  45. 'general' => array(
  46. 'title' => __( 'General', 'popup-maker' ),
  47. ),
  48. );
  49. $this->add_sections( $sections );
  50. if ( ! empty( $args['fields'] ) ) {
  51. $this->add_fields( $args['fields'] );
  52. }
  53. $this->args = $args;
  54. return $this;
  55. }
  56. /**
  57. * @param array $args
  58. *
  59. * @return mixed
  60. */
  61. public static function instance( $args = array() ) {
  62. $class = get_called_class();
  63. $class_key = md5( $class );
  64. if ( ! isset( self::$instances[ $class_key ] ) || ! self::$instances[ $class_key ] instanceof $class ) {
  65. self::$instances[ $class_key ] = new $class( $args );
  66. }
  67. return self::$instances[ $class_key ];
  68. }
  69. /**
  70. * This function should no longer be used.
  71. *
  72. * @deprecated 1.4 Replace with add_section()
  73. *
  74. * @param $id
  75. * @param $title
  76. * @param null $callback
  77. */
  78. public function register_section( $id, $title, $callback = null ) {
  79. $this->add_section( array(
  80. 'id' => $id,
  81. 'title' => $title,
  82. 'callback' => $callback,
  83. ) );
  84. }
  85. /**
  86. * @param $sections
  87. */
  88. public function add_sections( $sections ) {
  89. foreach ( $sections as $id => $section ) {
  90. if ( ! is_array( $section ) ) {
  91. $section = array(
  92. 'title' => $section,
  93. );
  94. }
  95. if ( empty( $section['id'] ) ) {
  96. $section['id'] = $id;
  97. }
  98. $this->add_section( $section );
  99. }
  100. }
  101. /**
  102. * @param $section
  103. */
  104. public function add_section( $section ) {
  105. $section = wp_parse_args( $section, array(
  106. 'id' => null,
  107. 'title' => '',
  108. 'hidden' => false,
  109. 'callback' => null,
  110. ) );
  111. $this->sections[ $section['id'] ] = $section;
  112. }
  113. /**
  114. * @param array $field
  115. */
  116. public function add_field( $field = array() ) {
  117. $field = wp_parse_args( $field, array(
  118. 'section' => 'general',
  119. 'type' => 'text',
  120. 'id' => null,
  121. 'label' => '',
  122. 'desc' => '',
  123. 'name' => null,
  124. 'templ_name' => null,
  125. 'size' => 'regular',
  126. 'options' => array(),
  127. 'std' => null,
  128. 'rows' => 5,
  129. 'cols' => 50,
  130. 'min' => 0,
  131. 'max' => 50,
  132. 'force_minmax' => false,
  133. 'step' => 1,
  134. 'select2' => null,
  135. 'object_type' => 'post_type',
  136. 'object_key' => 'post',
  137. 'post_type' => null,
  138. 'taxonomy' => null,
  139. 'multiple' => null,
  140. 'as_array' => false,
  141. 'placeholder' => null,
  142. 'checkbox_val' => 1,
  143. 'allow_blank' => true,
  144. 'readonly' => false,
  145. 'required' => false,
  146. 'disabled' => false,
  147. 'hook' => null,
  148. 'unit' => __( 'ms', 'popup-maker' ),
  149. 'priority' => null,
  150. 'doclink' => '',
  151. 'button_type' => 'submit',
  152. 'class' => '',
  153. ) );
  154. if ( ! $field['name'] ) {
  155. $field['name'] = $this->get_field_name( $field );
  156. }
  157. if ( ! $field['templ_name'] ) {
  158. $field['templ_name'] = $this->get_templ_name( $field );
  159. }
  160. $this->fields[ $field['section'] ][ $field['id'] ] = $field;
  161. }
  162. /**
  163. * @param array $fields
  164. * @param null $section
  165. */
  166. public function add_fields( $fields = array(), $section = null ) {
  167. /**
  168. * Switch the variables for backward compatibility with a
  169. * select few extensions that started using the v1.3 Settings API
  170. */
  171. if ( is_string( $fields ) && is_array( $section ) ) {
  172. $tmp = $fields;
  173. $fields = $section;
  174. $section = $tmp;
  175. }
  176. foreach ( $fields as $key => $field ) {
  177. // Either an undefined field or empty section. So lets skip it.
  178. if ( empty ( $field ) ) {
  179. continue;
  180. }
  181. $first_key = key( $field );
  182. if ( isset( $this->sections[ $key ] ) && is_array( $field[ $first_key ] ) ) {
  183. $this->add_fields( $field, $key );
  184. } // Process the fields.
  185. else {
  186. if ( $section ) {
  187. $field['section'] = $section;
  188. }
  189. if ( empty( $field['id'] ) && ! is_numeric( $key ) ) {
  190. $field['id'] = $key;
  191. }
  192. $this->add_field( $field );
  193. }
  194. }
  195. }
  196. /**
  197. * @return array
  198. */
  199. public function get_sections() {
  200. return $this->sections;
  201. }
  202. /**
  203. * @param null $section
  204. *
  205. * @return array
  206. */
  207. public function get_fields( $section = null ) {
  208. if ( ! $section ) {
  209. return $this->get_all_fields();
  210. }
  211. if ( ! isset( $this->fields[ $section ] ) ) {
  212. return array();
  213. }
  214. $non_priority_fields = array();
  215. $priority_fields = array();
  216. foreach ( $this->fields[ $section ] as $field_id => $field ) {
  217. if ( ! isset( $field['priority'] ) || is_null( $field['priority'] ) ) {
  218. $non_priority_fields[ $field_id ] = $field;
  219. } else {
  220. $priority_fields[ $field_id ] = $field;
  221. }
  222. }
  223. uasort( $priority_fields, array( $this, 'sort_by_priority' ) );
  224. $fields = $priority_fields + $non_priority_fields;
  225. return $fields;
  226. }
  227. /**
  228. * @return array
  229. */
  230. public function get_all_fields() {
  231. $all_fields = array();
  232. foreach ( $this->fields as $section => $fields ) {
  233. $all_fields[ $section ] = $this->get_fields( $section );
  234. }
  235. return $all_fields;
  236. }
  237. /**
  238. * Returns the a generated field name for given ID.
  239. *
  240. * Replaces {$prefix} with $field_prefix, {$section}
  241. * with $section and {$field} with $field
  242. *
  243. * @param $field
  244. *
  245. * @return string $field_name
  246. * @internal param $id
  247. * @internal param $section
  248. *
  249. * @uses public $field_prefix
  250. * @uses public $field_name_format
  251. *
  252. */
  253. public function get_field_name( $field ) {
  254. return str_replace( array(
  255. '{$prefix}',
  256. '{$section}',
  257. '{$field}',
  258. ), array(
  259. $this->field_prefix,
  260. $field['section'],
  261. $field['id'],
  262. ), $this->field_name_format );
  263. }
  264. /**
  265. * @param $section
  266. *
  267. * @return array
  268. */
  269. public function get_field_names( $section ) {
  270. $names = array();
  271. foreach ( $this->get_fields( $section ) as $id => $args ) {
  272. $names[] = $this->get_field_name( $args );
  273. }
  274. return $names;
  275. }
  276. /**
  277. * @param $args
  278. *
  279. * @return mixed|string
  280. */
  281. public function get_templ_name( $args ) {
  282. return str_replace( array(
  283. '{$prefix}',
  284. '{$section}',
  285. '{$field}',
  286. ), array(
  287. $this->field_prefix,
  288. $args['section'] != 'general' ? ".{$args['section']}" : "",
  289. $args['id'],
  290. ), $this->templ_value_format );
  291. }
  292. /**
  293. * @param string $section
  294. * @param array $values
  295. */
  296. function render_fields_by_section( $section = 'general', $values = array() ) {
  297. foreach ( $this->get_fields( $section ) as $key => $args ) {
  298. $value = isset( $values[ $args['id'] ] ) ? $values[ $args['id'] ] : null;
  299. $this->render_field( $args, $value );
  300. }
  301. }
  302. /**
  303. * @param array $values
  304. */
  305. function render_fields( $values = array() ) {
  306. foreach ( $this->get_all_fields() as $section => $fields ) {
  307. foreach ( $fields as $id => $args ) {
  308. $value = isset( $values[ $args['id'] ] ) ? $values[ $args['id'] ] : null;
  309. $this->render_field( $args, $value );
  310. }
  311. }
  312. }
  313. /**
  314. * @param array $args
  315. * @param null $value
  316. */
  317. public function render_field( $args = array(), $value = null ) {
  318. // If no type default to text.
  319. $type = ! empty( $args['type'] ) ? $args['type'] : 'text';
  320. /**
  321. * Check if any actions hooked to this type of field and load run those.
  322. */
  323. if ( has_action( "pum_{$type}_field" ) ) {
  324. do_action( "pum_{$type}_field", $args, $value );
  325. } else {
  326. /**
  327. * Check if override or custom function exists and load that.
  328. */
  329. if ( function_exists( "pum_{$type}_callback" ) ) {
  330. $function_name = "pum_{$type}_callback";
  331. } /**
  332. * Check if core method exists and load that.
  333. */ elseif ( method_exists( $this, $type . '_callback' ) ) {
  334. $function_name = array( $this, $type . '_callback' );
  335. } /**
  336. * No method exists, lets notify them the field type doesn't exist.
  337. */ else {
  338. $function_name = array( $this, 'missing_callback' );
  339. }
  340. /**
  341. * Call the determined method, passing the field args & $value to the callback.
  342. */
  343. call_user_func_array( $function_name, array( $args, $value ) );
  344. }
  345. }
  346. /**
  347. */
  348. public function render_templ_fields() {
  349. foreach ( $this->get_all_fields() as $section => $fields ) {
  350. foreach ( $fields as $id => $args ) {
  351. $this->render_templ_field( $args );
  352. }
  353. }
  354. }
  355. /**
  356. * @param string $section
  357. */
  358. public function render_templ_fields_by_section( $section = 'general' ) {
  359. foreach ( $this->get_fields( $section ) as $key => $args ) {
  360. $this->render_templ_field( $args );
  361. }
  362. }
  363. /**
  364. * @param array $args
  365. */
  366. public function render_templ_field( $args = array() ) {
  367. // If no type default to text.
  368. $type = ! empty( $args['type'] ) ? $args['type'] : 'text';
  369. /**
  370. * Check if any actions hooked to this type of field and load run those.
  371. */
  372. if ( has_action( "pum_{$type}_templ_field" ) ) {
  373. do_action( "pum_{$type}_templ_field", $args, $this );
  374. } else {
  375. /**
  376. * Check if override or custom function exists and load that.
  377. */
  378. if ( function_exists( "pum_{$type}_templ_callback" ) ) {
  379. $function_name = "pum_{$type}_templ_callback";
  380. } /**
  381. * Check if core method exists and load that.
  382. */ elseif ( method_exists( $this, $type . '_templ_callback' ) ) {
  383. $function_name = array( $this, $type . '_templ_callback' );
  384. } /**
  385. * Check if the field type is hook.
  386. */ elseif ( $type == 'hook' ) {
  387. $function_name = array( $this, 'hook_callback' );
  388. } /**
  389. * No method exists, lets notify them the field type doesn't exist.
  390. */ else {
  391. $function_name = array( $this, 'missing_callback' );
  392. }
  393. /**
  394. * Call the determined method, passing the field args & $value to the callback.
  395. */
  396. call_user_func_array( $function_name, array( $args, $this ) );
  397. }
  398. }
  399. /**
  400. * @param array $args
  401. */
  402. public function field_before( $args = array() ) {
  403. $classes = is_array( $args ) ? $this->field_classes( $args ) : ( is_string( $args ) ? $args : '' );
  404. ?><div class="<?php echo esc_attr( $classes ); ?>"><?php
  405. }
  406. /**
  407. *
  408. */
  409. public function field_after() {
  410. ?></div><?php
  411. }
  412. /**
  413. * @param $args
  414. * @param null $class
  415. *
  416. * @return string
  417. */
  418. public function field_classes( $args, $class = null ) {
  419. $args = wp_parse_args( $args, array(
  420. 'id' => '',
  421. 'class' => '',
  422. 'type' => '',
  423. 'desc' => '',
  424. 'doclink' => '',
  425. ) );
  426. $classes = array(
  427. 'pum-field',
  428. 'pum-field-' . $args['id'],
  429. 'pum-field-' . $args['type'],
  430. );
  431. if ( $args['doclink'] != '' ) {
  432. $classes[] = 'pum-field--has-doclink';
  433. }
  434. $classes[] = is_array( $args['class'] ) ? implode( ' ', $args['class'] ) : $args['class'];
  435. if ( isset( $class ) ) {
  436. $classes[] = is_array( $class ) ? implode( ' ', $class ) : $class;
  437. }
  438. return implode( ' ', $classes );
  439. }
  440. public function field_description( $args ) {
  441. if ( $args['desc'] != '' ) { ?>
  442. <p class="pum-desc"><?php echo esc_html( $args['desc'] ); ?></p><?php
  443. }
  444. /*
  445. if ( $args['doclink'] != '' ) { ?>
  446. <a href="<?php echo esc_url( $args['doclink'] ); ?>" target="_blank" class="pum-doclink dashicons dashicons-editor-help"></a><?php
  447. }
  448. */
  449. }
  450. public function field_label( $args ) {
  451. if ( ! empty( $args['label'] ) ) { ?>
  452. <label for="<?php echo esc_attr( $args['id'] ); ?>"><?php
  453. echo esc_html( $args['label'] );
  454. if ( $args['doclink'] != '' ) { ?>
  455. <a href="<?php echo esc_url( $args['doclink'] ); ?>" target="_blank" class="pum-doclink dashicons dashicons-editor-help"></a><?php
  456. } ?>
  457. </label><?php
  458. }
  459. }
  460. public function sanitize_field( $args, $value = null ) {
  461. // If no type default to text.
  462. $type = ! empty( $args['type'] ) ? $args['type'] : 'text';
  463. /**
  464. * Check if any actions hooked to this type of field and load run those.
  465. */
  466. if ( has_filter( "pum_{$type}_sanitize" ) ) {
  467. $value = apply_filters( "pum_{$type}_sanitize", $value, $args );
  468. } else {
  469. /**
  470. * Check if override or custom function exists and load that.
  471. */
  472. if ( function_exists( "pum_{$type}_sanitize" ) ) {
  473. $function_name = "pum_{$type}_sanitize";
  474. } /**
  475. * Check if core method exists and load that.
  476. */ elseif ( method_exists( $this, $type . '_sanitize' ) ) {
  477. $function_name = array( $this, $type . '_sanitize' );
  478. } else {
  479. $function_name = null;
  480. }
  481. if ( $function_name ) {
  482. /**
  483. * Call the determined method, passing the field args & $value to the callback.
  484. */
  485. $value = call_user_func_array( $function_name, array( $value, $args ) );
  486. }
  487. }
  488. $value = apply_filters( 'pum_settings_sanitize', $value, $args );
  489. return $value;
  490. }
  491. /**
  492. * Sanitize fields
  493. *
  494. * @param array $values
  495. *
  496. * @return array|mixed $input Sanitized value
  497. * @internal param array $input The value inputted in the field
  498. *
  499. */
  500. public function sanitize_fields( $values = array() ) {
  501. $sanitized_values = array();
  502. foreach ( $this->get_all_fields() as $section => $fields ) {
  503. foreach ( $fields as $field ) {
  504. $value = isset( $values[ $section ][ $field['id'] ] ) ? $values[ $section ][ $field['id'] ] : null;
  505. $value = $this->sanitize_field( $field, $value );
  506. if ( ! is_null( $value ) ) {
  507. $sanitized_values[ $section ][ $field['id'] ] = $value;
  508. }
  509. }
  510. }
  511. return $sanitized_values;
  512. }
  513. /**
  514. * Sort array by priority value
  515. *
  516. * @param $a
  517. * @param $b
  518. *
  519. * @return int
  520. */
  521. protected function sort_by_priority( $a, $b ) {
  522. if ( ! isset( $a['priority'] ) || ! isset( $b['priority'] ) || $a['priority'] === $b['priority'] ) {
  523. return 0;
  524. }
  525. return ( $a['priority'] < $b['priority'] ) ? - 1 : 1;
  526. }
  527. public function checkbox_sanitize( $value = null, $args = array() ) {
  528. if ( intval( $value ) == 1 ) {
  529. return 1;
  530. }
  531. return null;
  532. }
  533. /**
  534. * Hook Callback
  535. *
  536. * Adds a do_action() hook in place of the field
  537. *
  538. * @param array $args Arguments passed by the setting
  539. *
  540. * @return void
  541. */
  542. public function hook_callback( $args ) {
  543. do_action( 'popmake_' . $args['id'] );
  544. }
  545. }