PageRenderTime 48ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/classes/PodsForm.php

https://github.com/ElmsPark/pods
PHP | 966 lines | 510 code | 196 blank | 260 comment | 113 complexity | 901d9bfb80f9b6a6e294c4794b69d32f MD5 | raw file
Possible License(s): AGPL-1.0
  1. <?php
  2. /**
  3. * @package Pods
  4. */
  5. class PodsForm {
  6. /**
  7. * @var string
  8. */
  9. static $field = null;
  10. /**
  11. * @var string
  12. */
  13. static $field_group = null;
  14. /**
  15. * @var string
  16. */
  17. static $field_type = null;
  18. /**
  19. * @var array
  20. */
  21. static $field_types = array();
  22. /**
  23. * @var array
  24. */
  25. static $loaded = array();
  26. /**
  27. * @var int
  28. */
  29. static $form_counter = 0;
  30. /**
  31. * Generate UI for a Form and it's Fields
  32. *
  33. * @license http://www.gnu.org/licenses/gpl-2.0.html
  34. * @since 2.0.0
  35. */
  36. public function __construct () {
  37. }
  38. /**
  39. * Output a field's label
  40. *
  41. * @since 2.0.0
  42. */
  43. public static function label ( $name, $label, $help = '', $options = null ) {
  44. if ( is_array( $label ) ) {
  45. $options = $label;
  46. $label = $options[ 'label' ];
  47. if ( empty( $label ) )
  48. $label = ucwords( str_replace( '_', ' ', $name ) );
  49. $help = $options[ 'help' ];
  50. }
  51. else
  52. $options = self::options( null, $options );
  53. $label = apply_filters( 'pods_form_ui_label_text', $label, $name, $help, $options );
  54. $help = apply_filters( 'pods_form_ui_label_help', $help, $name, $label, $options );
  55. ob_start();
  56. $name_clean = self::clean( $name );
  57. $name_more_clean = self::clean( $name, true );
  58. $type = 'label';
  59. $attributes = array();
  60. $attributes[ 'class' ] = 'pods-form-ui-' . $type . ' pods-form-ui-' . $type . '-' . $name_more_clean;
  61. $attributes[ 'for' ] = ( false === strpos( $name_clean, 'pods-form-ui-' ) ? 'pods-form-ui-' : '' ) . $name_clean;
  62. $attributes = self::merge_attributes( $attributes, $name, $type, $options, false );
  63. pods_view( PODS_DIR . 'ui/fields/_label.php', compact( array_keys( get_defined_vars() ) ) );
  64. $output = ob_get_clean();
  65. return apply_filters( 'pods_form_ui_' . $type, $output, $name, $label, $help, $attributes, $options );
  66. }
  67. /**
  68. * Output a Field Comment Paragraph
  69. */
  70. public static function comment ( $name, $message = null, $options = null ) {
  71. $options = self::options( null, $options );
  72. $name_more_clean = self::clean( $name, true );
  73. if ( isset( $options[ 'description' ] ) && !empty( $options[ 'description' ] ) )
  74. $message = $options[ 'description' ];
  75. elseif ( empty( $message ) )
  76. return;
  77. $message = apply_filters( 'pods_form_ui_comment_text', $message, $name, $options );
  78. ob_start();
  79. $type = 'comment';
  80. $attributes = array();
  81. $attributes[ 'class' ] = 'pods-form-ui-' . $type . ' pods-form-ui-' . $type . '-' . $name_more_clean;
  82. $attributes = self::merge_attributes( $attributes, $name, $type, $options, false );
  83. pods_view( PODS_DIR . 'ui/fields/_comment.php', compact( array_keys( get_defined_vars() ) ) );
  84. $output = ob_get_clean();
  85. return apply_filters( 'pods_form_ui_' . $type, $output, $name, $message, $attributes, $options );
  86. }
  87. /**
  88. * Output a field
  89. *
  90. * @since 2.0.0
  91. */
  92. public static function field ( $name, $value, $type = 'text', $options = null, $pod = null, $id = null ) {
  93. $options = self::options( $type, $options );
  94. if ( null === $value || ( !empty( $pod ) && empty( $id ) ) )
  95. $value = self::default_value( $value, $type, $name, $options, $pod, $id );
  96. if ( false === self::permission( $type, $name, $options, null, $pod, $id ) )
  97. return false;
  98. $value = apply_filters( 'pods_form_ui_field_' . $type . '_value', $value, $name, $options, $pod, $id );
  99. $form_field_type = self::$field_type;
  100. ob_start();
  101. $helper = false;
  102. if ( 0 < strlen( pods_var_raw( 'input_helper', $options ) ) )
  103. $helper = pods_api()->load_helper( array( 'name' => $options[ 'input_helper' ] ) );
  104. if ( ( !isset( $options[ 'data' ] ) || empty( $options[ 'data' ] ) ) && is_object( self::$loaded[ $type ] ) && method_exists( self::$loaded[ $type ], 'data' ) )
  105. $data = $options[ 'data' ] = self::$loaded[ $type ]->data( $name, $value, $options, $pod, $id );
  106. if ( true === apply_filters( 'pods_form_ui_field_' . $type . '_override', false, $name, $value, $options, $pod, $id ) )
  107. do_action( 'pods_form_ui_field_' . $type, $name, $value, $options, $pod, $id );
  108. elseif ( !empty( $helper ) && 0 < strlen( pods_var_raw( 'code', $helper ) ) && ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) )
  109. eval( '?>' . $helper[ 'code' ] );
  110. elseif ( method_exists( get_class(), 'field_' . $type ) )
  111. echo call_user_func( array( get_class(), 'field_' . $type ), $name, $value, $options );
  112. elseif ( is_object( self::$loaded[ $type ] ) && method_exists( self::$loaded[ $type ], 'input' ) )
  113. self::$loaded[ $type ]->input( $name, $value, $options, $pod, $id );
  114. else
  115. do_action( 'pods_form_ui_field_' . $type, $name, $value, $options, $pod, $id );
  116. $output = ob_get_clean();
  117. return apply_filters( 'pods_form_ui_field_' . $type, $output, $name, $value, $options, $pod, $id );
  118. }
  119. /**
  120. * Output field type 'db'
  121. *
  122. * Used for field names and other places where only [a-z0-9_] is accepted
  123. *
  124. * @since 2.0.0
  125. */
  126. protected function field_db ( $name, $value = null, $options = null ) {
  127. $form_field_type = self::$field_type;
  128. ob_start();
  129. pods_view( PODS_DIR . 'ui/fields/_db.php', compact( array_keys( get_defined_vars() ) ) );
  130. $output = ob_get_clean();
  131. return apply_filters( 'pods_form_ui_field_db', $output, $name, $value, $options );
  132. }
  133. /**
  134. * Output a hidden field
  135. */
  136. protected function field_hidden ( $name, $value = null, $options = null ) {
  137. $form_field_type = self::$field_type;
  138. ob_start();
  139. pods_view( PODS_DIR . 'ui/fields/_hidden.php', compact( array_keys( get_defined_vars() ) ) );
  140. $output = ob_get_clean();
  141. return apply_filters( 'pods_form_ui_field_hidden', $output, $name, $value, $options );
  142. }
  143. /**
  144. * Output a row (label, field, and comment)
  145. */
  146. public static function row ( $name, $value, $type = 'text', $options = null, $pod = null, $id = null ) {
  147. $options = self::options( null, $options );
  148. ob_start();
  149. pods_view( PODS_DIR . 'ui/fields/_row.php', compact( array_keys( get_defined_vars() ) ) );
  150. $output = ob_get_clean();
  151. return apply_filters( 'pods_form_ui_field_row', $output, $name, $value, $options, $pod, $id );
  152. }
  153. /**
  154. * Output a field's attributes
  155. *
  156. * @since 2.0.0
  157. */
  158. public static function attributes ( $attributes, $name = null, $type = null, $options = null ) {
  159. $attributes = (array) apply_filters( 'pods_form_ui_field_' . $type . '_attributes', $attributes, $name, $options );
  160. foreach ( $attributes as $attribute => $value ) {
  161. if ( null === $value )
  162. continue;
  163. echo ' ' . esc_attr( (string) $attribute ) . '="' . esc_attr( (string) $value ) . '"';
  164. }
  165. }
  166. /**
  167. * Output a field's data (for use with jQuery)
  168. *
  169. * @since 2.0.0
  170. */
  171. public static function data ( $data, $name = null, $type = null, $options = null ) {
  172. $data = (array) apply_filters( 'pods_form_ui_field_' . $type . '_data', $data, $name, $options );
  173. foreach ( $data as $key => $value ) {
  174. if ( null === $value )
  175. continue;
  176. $key = sanitize_title( $key );
  177. if ( is_array( $value ) )
  178. $value = implode( ',', $value );
  179. echo ' data-' . esc_attr( (string) $key ) . '="' . esc_attr( (string) $value ) . '"';
  180. }
  181. }
  182. /**
  183. * Merge attributes and handle classes
  184. *
  185. * @since 2.0.0
  186. */
  187. public static function merge_attributes ( $attributes, $name = null, $type = null, $options = null, $classes = '' ) {
  188. $options = (array) $options;
  189. if ( !in_array( $type, array( 'label', 'comment' ) ) ) {
  190. $name_clean = self::clean( $name );
  191. $name_more_clean = self::clean( $name, true );
  192. $_attributes = array();
  193. $_attributes[ 'name' ] = $name;
  194. $_attributes[ 'data-name-clean' ] = $name_more_clean;
  195. if ( 0 < strlen( pods_var_raw( 'label', $options, '' ) ) )
  196. $_attributes[ 'data-label' ] = strip_tags( pods_var_raw( 'label', $options ) );
  197. $_attributes[ 'id' ] = 'pods-form-ui-' . $name_clean;
  198. $_attributes[ 'class' ] = 'pods-form-ui-field-type-' . $type . ' pods-form-ui-field-name-' . $name_more_clean;
  199. if ( isset( $options[ 'dependency' ] ) && false !== $options[ 'dependency' ] )
  200. $_attributes[ 'class' ] .= ' pods-dependent-toggle';
  201. $attributes = array_merge( $_attributes, (array) $attributes );
  202. }
  203. if ( isset( $options[ 'attributes' ] ) && is_array( $options[ 'attributes' ] ) && !empty( $options[ 'attributes' ] ) )
  204. $attributes = array_merge( $attributes, $options[ 'attributes' ] );
  205. if ( isset( $options[ 'class' ] ) && !empty( $options[ 'class' ] ) ) {
  206. if ( is_array( $options[ 'class' ] ) )
  207. $options[ 'class' ] = implode( ' ', $options[ 'class' ] );
  208. $options[ 'class' ] = (string) $options[ 'class' ];
  209. if ( isset( $attributes[ 'class' ] ) )
  210. $attributes[ 'class' ] = $attributes[ 'class' ] . ' ' . $options[ 'class' ];
  211. else
  212. $attributes[ 'class' ] = $options[ 'class' ];
  213. $attributes[ 'class' ] = trim( $attributes[ 'class' ] );
  214. }
  215. if ( !empty( $classes ) ) {
  216. if ( isset( $attributes[ 'class' ] ) )
  217. $attributes[ 'class' ] = $attributes[ 'class' ] . ' ' . $classes;
  218. else
  219. $attributes[ 'class' ] = $classes;
  220. }
  221. if ( 1 == pods_var( 'required', $options, 0 ) )
  222. $attributes[ 'class' ] .= ' pods-validate pods-validate-required';
  223. if ( isset( $options[ 'maxlength' ] ) && !empty( $options[ 'maxlength' ] ) )
  224. $attributes[ 'maxlength' ] = (int) $options[ 'maxlength' ];
  225. elseif ( isset( $options[ $type . '_max_length' ] ) && !empty( $options[ $type . '_max_length' ] ) )
  226. $attributes[ 'maxlength' ] = (int) $options[ $type . '_max_length' ];
  227. $attributes = (array) apply_filters( 'pods_form_ui_field_' . $type . '_merge_attributes', $attributes, $name, $options );
  228. return $attributes;
  229. }
  230. /*
  231. * Setup options for a field and store them for later use
  232. *
  233. * @since 2.0.0
  234. */
  235. /**
  236. * @static
  237. *
  238. * @param $type
  239. * @param $options
  240. *
  241. * @return array
  242. */
  243. public static function options ( $type, $options ) {
  244. $options = (array) $options;
  245. if ( isset( $options[ 'options' ] ) ) {
  246. $options_temp = $options[ 'options' ];
  247. unset( $options[ 'options' ] );
  248. $options = array_merge( $options_temp, $options );
  249. $override = array(
  250. 'class'
  251. );
  252. foreach ( $override as $check ) {
  253. if ( isset( $options_temp[ $check ] ) )
  254. $options[ $check ] = $options_temp[ $check ];
  255. }
  256. }
  257. $defaults = self::options_setup( $type, $options );
  258. $core_defaults = array(
  259. 'id' => 0,
  260. 'label' => '',
  261. 'description' => '',
  262. 'help' => '',
  263. 'default' => null,
  264. 'attributes' => array(),
  265. 'class' => '',
  266. 'grouped' => 0,
  267. );
  268. $defaults = array_merge( $core_defaults, $defaults );
  269. foreach ( $defaults as $option => $settings ) {
  270. $default = $settings;
  271. if ( is_array( $settings ) && isset( $settings[ 'default' ] ) )
  272. $default = $settings[ 'default' ];
  273. if ( !isset( $options[ $option ] ) )
  274. $options[ $option ] = $default;
  275. }
  276. return $options;
  277. }
  278. /*
  279. * Get options for a field type and setup defaults
  280. *
  281. * @since 2.0.0
  282. */
  283. /**
  284. * @static
  285. *
  286. * @param $type
  287. *
  288. * @return array|null
  289. */
  290. public static function options_setup ( $type = null ) {
  291. $core_defaults = array(
  292. 'id' => 0,
  293. 'name' => '',
  294. 'label' => '',
  295. 'description' => '',
  296. 'help' => '',
  297. 'default' => null,
  298. 'attributes' => array(),
  299. 'class' => '',
  300. 'type' => 'text',
  301. 'group' => 0,
  302. 'grouped' => 0,
  303. 'dependency' => false,
  304. 'depends-on' => array(),
  305. 'excludes-on' => array(),
  306. 'options' => array()
  307. );
  308. if ( null === $type )
  309. return $core_defaults;
  310. else
  311. self::field_loader( $type );
  312. $options = apply_filters( 'pods_field_' . $type . '_options', (array) self::$loaded[ $type ]->options(), $type, $core_defaults );
  313. return self::fields_setup( $options, $core_defaults );
  314. }
  315. /*
  316. * Get options for a field and setup defaults
  317. *
  318. * @since 2.0.0
  319. */
  320. /**
  321. * @static
  322. *
  323. * @param null $fields
  324. * @param null $core_defaults
  325. * @param bool $single
  326. *
  327. * @return array|null
  328. */
  329. public static function fields_setup ( $fields = null, $core_defaults = null, $single = false ) {
  330. if ( empty( $core_defaults ) ) {
  331. $core_defaults = array(
  332. 'id' => 0,
  333. 'name' => '',
  334. 'label' => '',
  335. 'description' => '',
  336. 'help' => '',
  337. 'default' => null,
  338. 'attributes' => array(),
  339. 'class' => '',
  340. 'type' => 'text',
  341. 'group' => 0,
  342. 'grouped' => 0,
  343. 'dependency' => false,
  344. 'depends-on' => array(),
  345. 'excludes-on' => array(),
  346. 'options' => array()
  347. );
  348. }
  349. if ( $single )
  350. $fields = array( $fields );
  351. foreach ( $fields as $f => $field ) {
  352. $fields[ $f ] = self::field_setup( $field, $core_defaults, pods_var( 'type', $field, 'text' ) );
  353. }
  354. if ( $single )
  355. $fields = $fields[ 0 ];
  356. return $fields;
  357. }
  358. /*
  359. * Get options for a field and setup defaults
  360. *
  361. * @since 2.0.0
  362. */
  363. /**
  364. * @static
  365. *
  366. * @param null $field
  367. * @param null $core_defaults
  368. * @param null $type
  369. *
  370. * @return array|null
  371. */
  372. public static function field_setup ( $field = null, $core_defaults = null, $type = null ) {
  373. $options = array();
  374. if ( empty( $core_defaults ) ) {
  375. $core_defaults = array(
  376. 'id' => 0,
  377. 'name' => '',
  378. 'label' => '',
  379. 'description' => '',
  380. 'help' => '',
  381. 'default' => null,
  382. 'attributes' => array(),
  383. 'class' => '',
  384. 'type' => 'text',
  385. 'group' => 0,
  386. 'grouped' => 0,
  387. 'dependency' => false,
  388. 'depends-on' => array(),
  389. 'excludes-on' => array(),
  390. 'options' => array()
  391. );
  392. if ( null !== $type ) {
  393. self::field_loader( $type );
  394. if ( method_exists( self::$loaded[ $type ], 'options' ) )
  395. $options = apply_filters( 'pods_field_' . $type . '_options', (array) self::$loaded[ $type ]->options(), $type );
  396. }
  397. }
  398. if ( !is_array( $field ) )
  399. $field = array( 'default' => $field );
  400. if ( isset( $field[ 'group' ] ) && is_array( $field[ 'group' ] ) ) {
  401. foreach ( $field[ 'group' ] as $g => $group_option ) {
  402. $field[ 'group' ][ $g ] = array_merge( $core_defaults, $group_option );
  403. }
  404. }
  405. $field = array_merge( $core_defaults, $field );
  406. foreach ( $options as $option => $settings ) {
  407. $v = null;
  408. if ( isset( $settings[ 'default' ] ) )
  409. $v = $settings[ 'default' ];
  410. if ( !isset( $field[ 'options' ][ $option ] ) )
  411. $field[ 'options' ][ $option ] = $v;
  412. }
  413. return $field;
  414. }
  415. /**
  416. * Setup dependency / exclusion classes
  417. *
  418. * @param array $options array( 'depends-on' => ..., 'excludes-on' => ...)
  419. * @param string $prefix
  420. *
  421. * @return string
  422. * @static
  423. * @since 2.0.0
  424. */
  425. public static function dependencies ( $options, $prefix = '' ) {
  426. $options = (array) $options;
  427. $depends_on = $excludes_on = array();
  428. if ( isset( $options[ 'depends-on' ] ) )
  429. $depends_on = (array) $options[ 'depends-on' ];
  430. if ( isset( $options[ 'excludes-on' ] ) )
  431. $excludes_on = (array) $options[ 'excludes-on' ];
  432. $classes = array();
  433. if ( !empty( $depends_on ) ) {
  434. $classes[] = 'pods-depends-on';
  435. foreach ( $depends_on as $depends => $on ) {
  436. $classes[] = 'pods-depends-on-' . $prefix . self::clean( $depends, true );
  437. if ( !is_bool( $on ) ) {
  438. $on = (array) $on;
  439. foreach ( $on as $o ) {
  440. $classes[] = 'pods-depends-on-' . $prefix . self::clean( $depends, true ) . '-' . self::clean( $o, true );
  441. }
  442. }
  443. }
  444. }
  445. if ( !empty( $excludes_on ) ) {
  446. $classes[] = 'pods-excludes-on';
  447. foreach ( $excludes_on as $excludes => $on ) {
  448. $classes[] = 'pods-excludes-on-' . $prefix . self::clean( $excludes, true );
  449. $on = (array) $on;
  450. foreach ( $on as $o ) {
  451. $classes[] = 'pods-excludes-on-' . $prefix . self::clean( $excludes, true ) . '-' . self::clean( $o, true );
  452. }
  453. }
  454. }
  455. $classes = implode( ' ', $classes );
  456. return $classes;
  457. }
  458. /**
  459. * Change the way the value of the field is displayed with Pods::get
  460. *
  461. * @param mixed $value
  462. * @param string $name
  463. * @param array $options
  464. * @param array $fields
  465. * @param array $pod
  466. * @param int $id
  467. * @param array $traverse
  468. *
  469. * @since 2.0.0
  470. */
  471. public static function display ( $type, $value = null, $name = null, $options = null, $pod = null, $id = null, $traverse = null ) {
  472. self::field_loader( $type );
  473. $tableless_field_types = apply_filters( 'pods_tableless_field_types', array( 'pick', 'file', 'avatar', 'taxonomy' ) );
  474. if ( method_exists( self::$loaded[ $type ], 'display' ) ) {
  475. if ( is_array( $value ) && in_array( $type, $tableless_field_types ) ) {
  476. foreach ( $value as &$display_value ) {
  477. $display_value = call_user_func_array( array( self::$loaded[ $type ], 'display' ), array( $display_value, $name, $options, $pod, $id, $traverse ) );
  478. }
  479. }
  480. else
  481. $value = call_user_func_array( array( self::$loaded[ $type ], 'display' ), array( $value, $name, $options, $pod, $id, $traverse ) );
  482. }
  483. return $value;
  484. }
  485. /**
  486. * Setup regex for JS / PHP
  487. *
  488. * @static
  489. *
  490. * @param $type
  491. * @param $options
  492. *
  493. * @return mixed|void
  494. * @since 2.0.0
  495. */
  496. public static function regex ( $type, $options ) {
  497. self::field_loader( $type );
  498. $regex = false;
  499. if ( method_exists( self::$loaded[ $type ], 'regex' ) )
  500. $regex = self::$loaded[ $type ]->regex( $options );
  501. $regex = apply_filters( 'pods_field_' . $type . '_regex', $regex, $options, $type );
  502. return $regex;
  503. }
  504. /**
  505. * Setup value preparation for sprintf
  506. *
  507. * @static
  508. *
  509. * @param $type
  510. * @param $options
  511. *
  512. * @return mixed|void
  513. * @since 2.0.0
  514. */
  515. public static function prepare ( $type, $options ) {
  516. self::field_loader( $type );
  517. $prepare = '%s';
  518. if ( method_exists( self::$loaded[ $type ], 'prepare' ) )
  519. $prepare = self::$loaded[ $type ]->prepare( $options );
  520. $prepare = apply_filters( 'pods_field_' . $type . '_prepare', $prepare, $options, $type );
  521. return $prepare;
  522. }
  523. /**
  524. * Validate a value before it's saved
  525. *
  526. * @param string $type
  527. * @param mixed $value
  528. * @param string $name
  529. * @param array $options
  530. * @param array $fields
  531. * @param array $pod
  532. * @param int $id
  533. * @param array|object $params
  534. *
  535. * @static
  536. *
  537. * @since 2.0.0
  538. */
  539. public static function validate ( $type, &$value, $name = null, $options = null, $fields = null, $pod = null, $id = null, $params = null ) {
  540. self::field_loader( $type );
  541. $validate = true;
  542. if ( 1 == pods_var( 'pre_save', $options, 1 ) && method_exists( self::$loaded[ $type ], 'validate' ) )
  543. $validate = self::$loaded[ $type ]->validate( $value, $name, $options, $fields, $pod, $id, $params );
  544. $validate = apply_filters( 'pods_field_' . $type . '_validate', $validate, $value, $name, $options, $fields, $pod, $id, $type, $params );
  545. return $validate;
  546. }
  547. /**
  548. * Change the value or perform actions after validation but before saving to the DB
  549. *
  550. * @param mixed $value
  551. * @param int $id
  552. * @param string $name
  553. * @param array $options
  554. * @param array $fields
  555. * @param array $pod
  556. * @param object $params
  557. *
  558. * @static
  559. *
  560. * @since 2.0.0
  561. */
  562. public static function pre_save ( $type, $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $params = null ) {
  563. self::field_loader( $type );
  564. if ( 1 == pods_var( 'pre_save', $options, 1 ) && method_exists( self::$loaded[ $type ], 'pre_save' ) )
  565. $value = self::$loaded[ $type ]->pre_save( $value, $id, $name, $options, $fields, $pod, $params );
  566. return $value;
  567. }
  568. /**
  569. * Check if a user has permission to be editing a field
  570. *
  571. * @param $type
  572. * @param null $name
  573. * @param null $options
  574. * @param null $fields
  575. * @param null $pod
  576. * @param null $id
  577. * @param null $params
  578. *
  579. * @static
  580. *
  581. * @since 2.0.0
  582. */
  583. public static function permission ( $type, $name = null, $options = null, $fields = null, $pod = null, $id = null, $params = null ) {
  584. $permission = pods_permission( $options );
  585. $permission = (boolean) apply_filters( 'pods_form_field_permission', $permission, $type, $name, $options, $fields, $pod, $id, $params );
  586. return $permission;
  587. }
  588. /**
  589. * Parse the default the value
  590. *
  591. * @since 2.0.0
  592. */
  593. public static function default_value ( $value, $type = 'text', $name = null, $options = null, $pod = null, $id = null ) {
  594. $default_value = pods_var_raw( 'default_value', $options, $value, null, true );
  595. $default = pods_var_raw( 'default', $options, $default_value, null, true );
  596. $default_value = str_replace( array( '{@', '}' ), '', trim( $default ) );
  597. if ( $default != $default_value )
  598. $default = pods_evaluate_tags( $default );
  599. $default = pods_var_raw( pods_var_raw( 'default_value_parameter', $options ), 'request', $default, null, true );
  600. if ( $default != $value )
  601. $value = $default;
  602. if ( is_array( $value ) )
  603. $value = pods_serial_comma( $value );
  604. return apply_filters( 'pods_form_field_default_value', $value, $default, $type, $options, $pod, $id );
  605. }
  606. /**
  607. * Clean a value for use in class / id
  608. *
  609. * @since 2.0.0
  610. */
  611. public static function clean ( $input, $noarray = false, $db_field = false ) {
  612. $input = str_replace( array( '--1', '__1' ), '00000', (string) $input );
  613. if ( false !== $noarray )
  614. $input = preg_replace( '/\[\d*\]/', '-', $input );
  615. $output = str_replace( array( '[', ']' ), '-', strtolower( $input ) );
  616. $output = preg_replace( '/([^a-z0-9-_])/', '', $output );
  617. $output = trim( str_replace( array( '__', '_', '--' ), '-', $output ), '-' );
  618. $output = str_replace( '00000', '--1', $output );
  619. if ( false !== $db_field )
  620. $output = str_replace( '-', '_', $output );
  621. return $output;
  622. }
  623. /**
  624. * Autoload a Field Type's class
  625. *
  626. * @param string $field_type Field Type indentifier
  627. * @param string $file The Field Type class file location
  628. *
  629. * @return string
  630. * @access public
  631. * @static
  632. * @since 2.0.0
  633. */
  634. public static function field_loader ( $field_type, $file = '' ) {
  635. if ( isset( self::$loaded[ $field_type ] ) ) {
  636. $class_vars = get_class_vars( get_class( self::$loaded[ $field_type ] ) ); // PHP 5.2.x workaround
  637. self::$field_group = ( isset( $class_vars[ 'group' ] ) ? $class_vars[ 'group' ] : '' );
  638. self::$field_type = $class_vars[ 'type' ];
  639. if ( 'Unknown' != $class_vars[ 'label' ] )
  640. return self::$loaded[ $field_type ];
  641. }
  642. include_once PODS_DIR . 'classes/PodsField.php';
  643. $field_type = self::clean( $field_type, true, true );
  644. $class_name = ucfirst( $field_type );
  645. $class_name = "PodsField_{$class_name}";
  646. if ( !class_exists( $class_name ) ) {
  647. if ( isset( self::$field_types[ $field_type ] ) && !empty( self::$field_types[ $field_type ][ 'file' ] ) )
  648. $file = self::$field_types[ $field_type ][ 'file' ];
  649. if ( !empty( $file ) && 0 < strlen( untrailingslashit( ABSPATH ) ) && 0 === strpos( $file, untrailingslashit( ABSPATH ) ) && file_exists( $file ) )
  650. include_once $file;
  651. else {
  652. $file = str_replace( '../', '', apply_filters( 'pods_form_field_include', PODS_DIR . 'classes/fields/' . basename( $field_type ) . '.php', $field_type ) );
  653. if ( 0 < strlen( untrailingslashit( WP_CONTENT_DIR ) ) && 0 === strpos( $file, untrailingslashit( WP_CONTENT_DIR ) ) && file_exists( $file ) )
  654. include_once $file;
  655. if ( 0 < strlen( untrailingslashit( ABSPATH ) ) && 0 === strpos( $file, untrailingslashit( ABSPATH ) ) && file_exists( $file ) )
  656. include_once $file;
  657. }
  658. }
  659. if ( class_exists( $class_name ) )
  660. $class = new $class_name();
  661. else {
  662. $class = new PodsField();
  663. $class_name = 'PodsField';
  664. }
  665. $class_vars = get_class_vars( $class_name ); // PHP 5.2.x workaround
  666. self::$field_group = ( isset( $class_vars[ 'group' ] ) ? $class_vars[ 'group' ] : '' );
  667. self::$field_type = $class_vars[ 'type' ];
  668. self::$loaded[ $field_type ] =& $class;
  669. return self::$loaded[ $field_type ];
  670. }
  671. /**
  672. * Run a method from a Field Type's class
  673. *
  674. * @param string $field_type Field Type indentifier
  675. * @param string $method Method name
  676. * @param mixed $arg More arguments
  677. *
  678. * @return mixed
  679. * @access public
  680. * @static
  681. * @since 2.0.0
  682. */
  683. public static function field_method () {
  684. $args = func_get_args();
  685. if ( empty( $args ) && count( $args ) < 2 )
  686. return false;
  687. $field_type = array_shift( $args );
  688. $method = array_shift( $args );
  689. $class = self::field_loader( $field_type );
  690. if ( method_exists( $class, $method ) )
  691. return call_user_func_array( array( $class, $method ), $args );
  692. return false;
  693. }
  694. /**
  695. * Add a new Pod field type
  696. *
  697. * @param string $type The new field type identifier
  698. * @param string $file The new field type class file location
  699. *
  700. * @since 2.3.0
  701. */
  702. public static function register_field_type ( $type, $file = null ) {
  703. $field_type = pods_transient_get( 'pods_field_type_' . $type );
  704. if ( empty( $field_type ) || $field_type[ 'type' ] != $type || $field_type[ 'file' ] != $file ) {
  705. self::field_loader( $type, $file );
  706. $class_vars = get_class_vars( get_class( self::$loaded[ $type ] ) ); // PHP 5.2.x workaround
  707. self::$field_types[ $type ] = $class_vars;
  708. self::$field_types[ $type ][ 'file' ] = $file;
  709. pods_transient_set( 'pods_field_type_' . $type, self::$field_types[ $type ] );
  710. }
  711. else
  712. self::$field_types[ $type ] = $field_type;
  713. return self::$field_types[ $type ];
  714. }
  715. /**
  716. * Get a list of all available field types and include
  717. *
  718. * @return array
  719. *
  720. * @since 2.3.0
  721. */
  722. public static function field_types () {
  723. $field_types = array(
  724. 'text',
  725. 'website',
  726. 'phone',
  727. 'email',
  728. 'password',
  729. 'paragraph',
  730. 'wysiwyg',
  731. 'code',
  732. 'datetime',
  733. 'date',
  734. 'time',
  735. 'number',
  736. 'currency',
  737. 'file',
  738. 'avatar',
  739. 'pick',
  740. 'boolean',
  741. 'color',
  742. 'slug'
  743. );
  744. if ( pods_developer() )
  745. $field_types[] = 'loop';
  746. $field_types = array_merge( $field_types, array_keys( self::$field_types ) );
  747. $field_types = array_filter( array_unique( $field_types ) );
  748. $types = apply_filters( 'pods_api_field_types', $field_types );
  749. $field_types = pods_transient_get( 'pods_field_types' );
  750. if ( empty( $field_types ) || count( $types ) != count( $field_types ) ) {
  751. $field_types = array();
  752. foreach ( $types as $field_type ) {
  753. $file = null;
  754. if ( isset( self::$field_types[ $field_type ] ) )
  755. $file = self::$field_types[ $field_type ][ 'file' ];
  756. self::field_loader( $field_type, $file );
  757. if ( !isset( self::$loaded[ $field_type ] ) || !is_object( self::$loaded[ $field_type ] ) )
  758. continue;
  759. $class_vars = get_class_vars( get_class( self::$loaded[ $field_type ] ) ); // PHP 5.2.x workaround
  760. $field_types[ $field_type ] = $class_vars;
  761. $field_types[ $field_type ][ 'file' ] = $file;
  762. }
  763. self::$field_types = $field_types;
  764. pods_transient_set( 'pods_field_types', self::$field_types );
  765. }
  766. else
  767. self::$field_types = array_merge( $field_types, self::$field_types );
  768. return self::$field_types;
  769. }
  770. }