Pods

The Pods - Custom Content Types and Fields Pods class.

Defined (1)

The class is defined in the following location(s).

/classes/Pods.php  
  1. class Pods implements Iterator { 
  2.  
  3. /** 
  4. * @var bool 
  5. */ 
  6. private $iterator = false; 
  7.  
  8. /** 
  9. * @var PodsAPI 
  10. */ 
  11. public $api; 
  12.  
  13. /** 
  14. * @var PodsData 
  15. */ 
  16. public $data; 
  17.  
  18. /** 
  19. * @var PodsData 
  20. */ 
  21. public $alt_data; 
  22.  
  23. /** 
  24. * @var array Array of pod item arrays 
  25. */ 
  26. public $rows = array(); 
  27.  
  28. /** 
  29. * @var array Current pod item array 
  30. */ 
  31. public $row = array(); 
  32.  
  33. /** 
  34. * @var int 
  35. */ 
  36. private $row_number = -1; 
  37.  
  38. /** 
  39. * @var array Override pod item array 
  40. */ 
  41. public $row_override = array(); 
  42.  
  43. /** 
  44. * @var bool 
  45. */ 
  46. public $display_errors = true; 
  47.  
  48. /** 
  49. * @var array|bool|mixed|null|void 
  50. */ 
  51. public $pod_data; 
  52.  
  53. /** 
  54. * @var array 
  55. */ 
  56. public $params = array(); 
  57.  
  58. /** 
  59. * @var string 
  60. */ 
  61. public $pod = ''; 
  62.  
  63. /** 
  64. * @var int 
  65. */ 
  66. public $pod_id = 0; 
  67.  
  68. /** 
  69. * @var array 
  70. */ 
  71. public $fields = array(); 
  72.  
  73. /** 
  74. * @var array 
  75. */ 
  76. public $filters = array(); 
  77.  
  78. /** 
  79. * @var string 
  80. */ 
  81. public $detail_page; 
  82.  
  83. /** 
  84. * @var int 
  85. */ 
  86. public $id = 0; 
  87.  
  88. /** 
  89. * @var int 
  90. */ 
  91. public $limit = 15; 
  92.  
  93. /** 
  94. * @var int 
  95. */ 
  96. public $offset = 0; 
  97.  
  98. /** 
  99. * @var string 
  100. */ 
  101. public $page_var = 'pg'; 
  102.  
  103. /** 
  104. * @var int|mixed 
  105. */ 
  106. public $page = 1; 
  107.  
  108. /** 
  109. * @var bool 
  110. */ 
  111. public $pagination = true; 
  112.  
  113. /** 
  114. * @var bool 
  115. */ 
  116. public $search = true; 
  117.  
  118. /** 
  119. * @var string 
  120. */ 
  121. public $search_var = 'search'; 
  122.  
  123. /** 
  124. * @var string 
  125. */ 
  126. public $search_mode = 'int'; // int | text | text_like 
  127.  
  128. /** 
  129. * @var int 
  130. */ 
  131. public $total = 0; 
  132.  
  133. /** 
  134. * @var int 
  135. */ 
  136. public $total_found = 0; 
  137.  
  138. /** 
  139. * @var array 
  140. */ 
  141. public $ui = array(); 
  142.  
  143. /** 
  144. * @var mixed SEO related vars for Pod Pages 
  145. */ 
  146. public $page_template; 
  147. public $body_classes; 
  148. public $meta = array(); 
  149. public $meta_properties = array(); 
  150. public $meta_extra = ''; 
  151.  
  152. /** 
  153. * @var string Last SQL query used by a find() 
  154. */ 
  155. public $sql; 
  156.  
  157. /** 
  158. * @var 
  159. */ 
  160. public $deprecated; 
  161.  
  162. public $datatype; 
  163.  
  164. public $datatype_id; 
  165.  
  166. /** 
  167. * Constructor - Pods Framework core 
  168. * @param string $pod The pod name 
  169. * @param mixed $id (optional) The ID or slug, to load a single record; Provide array of $params to run 'find' 
  170. * @return \Pods 
  171. * @license http://www.gnu.org/licenses/gpl-2.0.html 
  172. * @since 1.0.0 
  173. * @link http://pods.io/docs/pods/ 
  174. */ 
  175. public function __construct ( $pod = null, $id = null ) { 
  176. if ( null === $pod ) { 
  177. $queried_object = get_queried_object(); 
  178.  
  179. if ( $queried_object ) { 
  180. $id_lookup = true; 
  181.  
  182. // Post Type Singular 
  183. if ( isset( $queried_object->post_type ) ) { 
  184. $pod = $queried_object->post_type; 
  185. // Term Archive 
  186. elseif ( isset( $queried_object->taxonomy ) ) { 
  187. $pod = $queried_object->taxonomy; 
  188. // Author Archive 
  189. elseif ( isset( $queried_object->user_login ) ) { 
  190. $pod = 'user'; 
  191. // Post Type Archive 
  192. elseif ( isset( $queried_object->public ) && isset( $queried_object->name ) ) { 
  193. $pod = $queried_object->name; 
  194.  
  195. $id_lookup = false; 
  196.  
  197. if ( null === $id && $id_lookup ) { 
  198. $id = get_queried_object_id(); 
  199.  
  200. $this->api = pods_api( $pod ); 
  201. $this->api->display_errors =& $this->display_errors; 
  202.  
  203. $this->data = pods_data( $this->api, $id, false ); 
  204. PodsData::$display_errors =& $this->display_errors; 
  205.  
  206. // Set up page variable 
  207. if ( pods_strict( false ) ) { 
  208. $this->page = 1; 
  209. $this->pagination = false; 
  210. $this->search = false; 
  211. else { 
  212. // Get the page variable 
  213. $this->page = pods_var( $this->page_var, 'get' ); 
  214. $this->page = ( empty( $this->page ) ? 1 : max( pods_absint( $this->page ), 1 ) ); 
  215.  
  216. // Set default pagination handling to on/off 
  217. if ( defined( 'PODS_GLOBAL_POD_PAGINATION' ) ) { 
  218. if ( !PODS_GLOBAL_POD_PAGINATION ) { 
  219. $this->page = 1; 
  220. $this->pagination = false; 
  221. else 
  222. $this->pagination = true; 
  223.  
  224. // Set default search to on/off 
  225. if ( defined( 'PODS_GLOBAL_POD_SEARCH' ) ) { 
  226. if ( PODS_GLOBAL_POD_SEARCH ) 
  227. $this->search = true; 
  228. else 
  229. $this->search = false; 
  230.  
  231. // Set default search mode 
  232. $allowed_search_modes = array( 'int', 'text', 'text_like' ); 
  233.  
  234. if ( defined( 'PODS_GLOBAL_POD_SEARCH_MODE' ) && in_array( PODS_GLOBAL_POD_SEARCH_MODE, $allowed_search_modes ) ) 
  235. $this->search_mode = PODS_GLOBAL_POD_SEARCH_MODE; 
  236.  
  237. // Sync Settings 
  238. $this->data->page =& $this->page; 
  239. $this->data->limit =& $this->limit; 
  240. $this->data->pagination =& $this->pagination; 
  241. $this->data->search =& $this->search; 
  242. $this->data->search_mode =& $this->search_mode; 
  243.  
  244. // Sync Pod Data 
  245. $this->api->pod_data =& $this->data->pod_data; 
  246. $this->pod_data =& $this->api->pod_data; 
  247. $this->api->pod_id =& $this->data->pod_id; 
  248. $this->pod_id =& $this->api->pod_id; 
  249. $this->datatype_id =& $this->pod_id; 
  250. $this->api->pod =& $this->data->pod; 
  251. $this->pod =& $this->api->pod; 
  252. $this->datatype =& $this->pod; 
  253. $this->api->fields =& $this->data->fields; 
  254. $this->fields =& $this->api->fields; 
  255. $this->detail_page =& $this->data->detail_page; 
  256. $this->id =& $this->data->id; 
  257. $this->row =& $this->data->row; 
  258. $this->rows =& $this->data->data; 
  259. $this->row_number =& $this->data->row_number; 
  260. $this->sql =& $this->data->sql; 
  261.  
  262. if ( is_array( $id ) || is_object( $id ) ) 
  263. $this->find( $id ); 
  264.  
  265. /** 
  266. * Whether this Pod object is valid or not 
  267. * @return bool 
  268. * @since 2.0 
  269. */ 
  270. public function valid () { 
  271. if ( empty( $this->pod_id ) ) 
  272. return false; 
  273.  
  274. if ( $this->iterator ) 
  275. return isset( $this->rows[ $this->row_number ] ); 
  276.  
  277. return true; 
  278.  
  279. /** 
  280. * Check if in Iterator mode 
  281. * @return bool 
  282. * @since 2.3.4 
  283. * @link http://www.php.net/manual/en/class.iterator.php 
  284. */ 
  285. public function is_iterator () { 
  286. return $this->iterator; 
  287.  
  288. /** 
  289. * Turn off Iterator mode to off 
  290. * @return void 
  291. * @since 2.3.4 
  292. * @link http://www.php.net/manual/en/class.iterator.php 
  293. */ 
  294. public function stop_iterator () { 
  295. $this->iterator = false; 
  296.  
  297. return; 
  298.  
  299. /** 
  300. * Rewind Iterator 
  301. * @return void|boolean 
  302. * @since 2.3.4 
  303. * @link http://www.php.net/manual/en/class.iterator.php 
  304. */ 
  305. public function rewind () { 
  306. if ( $this->iterator ) { 
  307. $this->row_number = 0; 
  308.  
  309. return; 
  310.  
  311. return false; 
  312.  
  313. /** 
  314. * Get current Iterator row 
  315. * @return mixed|boolean 
  316. * @since 2.3.4 
  317. * @link http://www.php.net/manual/en/class.iterator.php 
  318. */ 
  319. public function current () { 
  320. if ( $this->iterator && $this->fetch() ) 
  321. return $this; 
  322.  
  323. return false; 
  324.  
  325. /** 
  326. * Get current Iterator key 
  327. * @return int|boolean 
  328. * @since 2.3.4 
  329. * @link http://www.php.net/manual/en/class.iterator.php 
  330. */ 
  331. public function key () { 
  332. if ( $this->iterator ) 
  333. return $this->row_number; 
  334.  
  335. return false; 
  336.  
  337. /** 
  338. * Move onto the next Iterator row 
  339. * @return void|boolean 
  340. * @since 2.3.4 
  341. * @link http://www.php.net/manual/en/class.iterator.php 
  342. */ 
  343. public function next () { 
  344. if ( $this->iterator ) { 
  345. $this->row_number++; 
  346.  
  347. return; 
  348.  
  349. return false; 
  350.  
  351. /** 
  352. * Whether a Pod item exists or not when using fetch() or construct with an ID or slug 
  353. * @return bool 
  354. * @since 2.0 
  355. */ 
  356. public function exists () { 
  357. if ( empty( $this->row ) ) 
  358. return false; 
  359.  
  360. return true; 
  361.  
  362. /** 
  363. * Return an array of all rows returned from a find() call. 
  364. * Most of the time, you will want to loop through data using fetch() 
  365. * instead of using this function. 
  366. * @return array|bool An array of all rows returned from a find() call, or false if no items returned 
  367. * @since 2.0 
  368. * @link http://pods.io/docs/data/ 
  369. */ 
  370. public function data () { 
  371. do_action( 'pods_pods_data', $this ); 
  372.  
  373. if ( empty( $this->rows ) ) 
  374. return false; 
  375.  
  376. return (array) $this->rows; 
  377.  
  378. /** 
  379. * Return a field input for a specific field 
  380. * @param string|array $field Field name or Field data array 
  381. * @param string $field Input field name to use (overrides default name) 
  382. * @param mixed $value Current value to use 
  383. * @return string Field Input HTML 
  384. * @since 2.3.10 
  385. */ 
  386. public function input( $field, $input_name = null, $value = '__null' ) { 
  387.  
  388. // Field data override 
  389. if ( is_array( $field ) ) { 
  390. $field_data = $field; 
  391. $field = pods_var_raw( 'name', $field ); 
  392. // Get field data from field name 
  393. else { 
  394. $field_data = $this->fields( $field ); 
  395.  
  396. if ( !empty( $field_data ) ) { 
  397. $field_type = pods_var_raw( 'type', $field_data ); 
  398.  
  399. if ( empty( $input_name ) ) { 
  400. $input_name = $field; 
  401.  
  402. if ( '__null' == $value ) { 
  403. $value = $this->field( array( 'name' => $field, 'in_form' => true ) ); 
  404.  
  405. return PodsForm::field( $input_name, $value, $field_type, $field_data, $this, $this->id() ); 
  406.  
  407. return ''; 
  408.  
  409.  
  410. /** 
  411. * Return field array from a Pod, a field's data, or a field option 
  412. * @param null $field 
  413. * @param null $option 
  414. * @return bool|mixed 
  415. * @since 2.0 
  416. */ 
  417. public function fields ( $field = null, $option = null ) { 
  418. // No fields found 
  419. if ( empty( $this->fields ) ) 
  420. $field_data = array(); 
  421. // Return all fields 
  422. elseif ( empty( $field ) ) 
  423. $field_data = (array) $this->fields; 
  424. // Field not found 
  425. elseif ( !isset( $this->fields[ $field ] ) ) 
  426. $field_data = array(); 
  427. // Return all field data 
  428. elseif ( empty( $option ) ) 
  429. $field_data = $this->fields[ $field ]; 
  430. else { 
  431. // Merge options 
  432. $options = array_merge( $this->fields[ $field ], $this->fields[ $field ][ 'options' ] ); 
  433.  
  434. $field_data = null; 
  435.  
  436. // Get a list of available items from a relationship field 
  437. if ( 'data' == $option && in_array( pods_var_raw( 'type', $options ), PodsForm::tableless_field_types() ) ) { 
  438. $field_data = PodsForm::field_method( 'pick', 'get_field_data', $options ); 
  439. // Return option 
  440. elseif ( isset( $options[ $option ] ) ) { 
  441. $field_data = $options[ $option ]; 
  442.  
  443. /** 
  444. * Modify the field data before returning 
  445. * @since unknown 
  446. * @param array $field_data The data for the field. 
  447. * @param string|null $field The specific field that data is being return for, if set when method is called or null. 
  448. * @param string|null $option Value of option param when method was called. Can be used to get a list of available items from a relationship field. 
  449. * @param Pods|object $this The current Pods class instance. 
  450. */ 
  451. return apply_filters( 'pods_pods_fields', $field_data, $field, $option, $this ); 
  452.  
  453.  
  454. /** 
  455. * Return row array for an item 
  456. * @return array 
  457. * @since 2.0 
  458. */ 
  459. public function row () { 
  460. do_action( 'pods_pods_row', $this ); 
  461.  
  462. if ( !is_array( $this->row ) ) 
  463. return false; 
  464.  
  465. return (array) $this->row; 
  466.  
  467. /** 
  468. * Return the output for a field. If you want the raw value for use in PHP for custom manipulation,  
  469. * you will want to use field() instead. This function will automatically convert arrays into a 
  470. * list of text such as "Rick, John, and Gary" 
  471. * @param string|array $name The field name, or an associative array of parameters 
  472. * @param boolean $single (optional) For tableless fields, to return an array or the first 
  473. * @return string|null|false The output from the field, null if the field doesn't exist, false if no value returned for tableless fields 
  474. * @since 2.0 
  475. * @link http://pods.io/docs/display/ 
  476. */ 
  477. public function display ( $name, $single = null ) { 
  478. $defaults = array( 
  479. 'name' => $name,  
  480. 'single' => $single,  
  481. 'display' => true,  
  482. 'serial_params' => null 
  483. ); 
  484.  
  485. if ( is_array( $name ) || is_object( $name ) ) { 
  486. $defaults[ 'name' ] = null; 
  487. $params = (object) array_merge( $defaults, (array) $name ); 
  488. elseif ( is_array( $single ) || is_object( $single ) ) { 
  489. $defaults[ 'single' ] = null; 
  490. $params = (object) array_merge( $defaults, (array) $single ); 
  491. else 
  492. $params = $defaults; 
  493.  
  494. $params = (object) $params; 
  495.  
  496. $value = $this->field( $params ); 
  497.  
  498. if ( is_array( $value ) ) { 
  499. $fields = $this->fields; 
  500.  
  501. if ( isset( $this->pod_data[ 'object_fields' ] ) ) { 
  502. $fields = array_merge( $fields, $this->pod_data[ 'object_fields' ] ); 
  503.  
  504. $serial_params = array( 
  505. 'field' => $params->name,  
  506. 'fields' => $fields 
  507. ); 
  508.  
  509. if ( !empty( $params->serial_params ) && is_array( $params->serial_params ) ) 
  510. $serial_params = array_merge( $serial_params, $params->serial_params ); 
  511.  
  512. $value = pods_serial_comma( $value, $serial_params ); 
  513.  
  514. return $value; 
  515.  
  516. /** 
  517. * Return the raw output for a field If you want the raw value for use in PHP for custom manipulation,  
  518. * you will want to use field() instead. This function will automatically convert arrays into a 
  519. * list of text such as "Rick, John, and Gary" 
  520. * @param string|array $name The field name, or an associative array of parameters 
  521. * @param boolean $single (optional) For tableless fields, to return an array or the first 
  522. * @return string|null|false The output from the field, null if the field doesn't exist, false if no value returned for tableless fields 
  523. * @since 2.0 
  524. * @link http://pods.io/docs/display/ 
  525. */ 
  526. public function raw ( $name, $single = null ) { 
  527. $defaults = array( 
  528. 'name' => $name,  
  529. 'single' => $single,  
  530. 'raw' => true 
  531. ); 
  532.  
  533. if ( is_array( $name ) || is_object( $name ) ) { 
  534. $defaults[ 'name' ] = null; 
  535. $params = (object) array_merge( $defaults, (array) $name ); 
  536. elseif ( is_array( $single ) || is_object( $single ) ) { 
  537. $defaults[ 'single' ] = null; 
  538. $params = (object) array_merge( $defaults, (array) $single ); 
  539. else 
  540. $params = (object) $defaults; 
  541.  
  542. $value = $this->field( $params ); 
  543.  
  544. return $value; 
  545.  
  546. /** 
  547. * Return the value for a field. 
  548. * If you are getting a field for output in a theme, most of the time you will want to use display() instead. 
  549. * This function will return arrays for relationship and file fields. 
  550. * @param string|array $name The field name, or an associative array of parameters 
  551. * @param boolean $single (optional) For tableless fields, to return the whole array or the just the first item, or an associative array of parameters 
  552. * @param boolean $raw (optional) Whether to return the raw value, or to run through the field type's display method, or an associative array of parameters 
  553. * @return mixed|null Value returned depends on the field type, null if the field doesn't exist, false if no value returned for tableless fields 
  554. * @since 2.0 
  555. * @link http://pods.io/docs/field/ 
  556. */ 
  557. public function field ( $name, $single = null, $raw = false ) { 
  558. global $sitepress; 
  559.  
  560. $defaults = array( 
  561. 'name' => $name,  
  562. 'orderby' => null,  
  563. 'single' => $single,  
  564. 'params' => null,  
  565. 'in_form' => false,  
  566. 'raw' => $raw,  
  567. 'raw_display' => false,  
  568. 'display' => false,  
  569. 'get_meta' => false,  
  570. 'output' => null,  
  571. 'deprecated' => false,  
  572. 'args' => array() // extra data to send to field handlers 
  573. ); 
  574.  
  575. if ( is_array( $name ) || is_object( $name ) ) { 
  576. $defaults[ 'name' ] = null; 
  577. $params = (object) array_merge( $defaults, (array) $name ); 
  578. elseif ( is_array( $single ) || is_object( $single ) ) { 
  579. $defaults[ 'single' ] = null; 
  580. $params = (object) array_merge( $defaults, (array) $single ); 
  581. elseif ( is_array( $raw ) || is_object( $raw ) ) { 
  582. $defaults[ 'raw' ] = false; 
  583. $params = (object) array_merge( $defaults, (array) $raw ); 
  584. else 
  585. $params = (object) $defaults; 
  586.  
  587. if ( $params->in_form ) { 
  588. $params->output = 'ids'; 
  589. elseif ( null === $params->output ) { 
  590. /** 
  591. * Override the way realted fields are output 
  592. * @param string $output How to output related fields. Default is 'arrays'. Options: id|name|object|array|pod 
  593. * @param array|object $row Current row being outputted. 
  594. * @param array $params Params array passed to field(). 
  595. * @param object|Pods $this Current Pods object. 
  596. */ 
  597. $params->output = apply_filters( 'pods_pods_field_related_output_type', 'arrays', $this->row, $params, $this ); 
  598.  
  599. if ( in_array( $params->output, array( 'id', 'name', 'object', 'array', 'pod' ) ) ) 
  600. $params->output .= 's'; 
  601.  
  602. // Support old $orderby variable 
  603. if ( null !== $params->single && is_string( $params->single ) && empty( $params->orderby ) ) { 
  604. if ( ! class_exists( 'Pod' ) || Pod::$deprecated_notice ) { 
  605. pods_deprecated( 'Pods::field', '2.0', 'Use $params[ \'orderby\' ] instead' ); 
  606.  
  607. $params->orderby = $params->single; 
  608. $params->single = false; 
  609.  
  610. if ( null !== $params->single ) 
  611. $params->single = (boolean) $params->single; 
  612.  
  613. $params->name = trim( $params->name ); 
  614. if ( is_array( $params->name ) || strlen( $params->name ) < 1 ) 
  615. return null; 
  616.  
  617. $params->full_name = $params->name; 
  618.  
  619. $value = null; 
  620.  
  621. if ( isset( $this->row_override[ $params->name ] ) ) 
  622. $value = $this->row_override[ $params->name ]; 
  623.  
  624. if ( false === $this->row() ) { 
  625. if ( false !== $this->data() ) 
  626. $this->fetch(); 
  627. else 
  628. return $value; 
  629.  
  630. if ( $this->data->field_id == $params->name ) { 
  631. if ( isset( $this->row[ $params->name ] ) ) 
  632. return $this->row[ $params->name ]; 
  633. elseif ( null !== $value ) 
  634. return $value; 
  635.  
  636. return 0; 
  637.  
  638. $tableless_field_types = PodsForm::tableless_field_types(); 
  639. $simple_tableless_objects = PodsForm::simple_tableless_objects(); 
  640.  
  641. $params->traverse = array(); 
  642.  
  643. if ( in_array( $params->name, array( '_link', 'detail_url' ) ) || ( in_array( $params->name, array( 'permalink', 'the_permalink' ) ) && in_array( $this->pod_data[ 'type' ], array( 'post_type', 'media' ) ) ) ) { 
  644. if ( 0 < strlen( $this->detail_page ) ) 
  645. $value = get_home_url() . '/' . $this->do_magic_tags( $this->detail_page ); 
  646. elseif ( in_array( $this->pod_data[ 'type' ], array( 'post_type', 'media' ) ) ) 
  647. $value = get_permalink( $this->id() ); 
  648. elseif ( 'taxonomy' == $this->pod_data[ 'type' ] ) 
  649. $value = get_term_link( $this->id(), $this->pod_data[ 'name' ] ); 
  650. elseif ( 'user' == $this->pod_data[ 'type' ] ) 
  651. $value = get_author_posts_url( $this->id() ); 
  652. elseif ( 'comment' == $this->pod_data[ 'type' ] ) 
  653. $value = get_comment_link( $this->id() ); 
  654.  
  655. $field_data = $last_field_data = false; 
  656. $field_type = false; 
  657.  
  658. $first_field = explode( '.', $params->name ); 
  659. $first_field = $first_field[ 0 ]; 
  660.  
  661. if ( isset( $this->fields[ $first_field ] ) ) { 
  662. $field_data = $this->fields[ $first_field ]; 
  663. $field_type = 'field'; 
  664. elseif ( !empty( $this->pod_data[ 'object_fields' ] ) ) { 
  665. if ( isset( $this->pod_data[ 'object_fields' ][ $first_field ] ) ) { 
  666. $field_data = $this->pod_data[ 'object_fields' ][ $first_field ]; 
  667. $field_type = 'object_field'; 
  668. else { 
  669. foreach ( $this->pod_data[ 'object_fields' ] as $object_field => $object_field_opt ) { 
  670. if ( in_array( $first_field, $object_field_opt[ 'alias' ] ) ) { 
  671. if ( $first_field == $params->name ) 
  672. $params->name = $object_field; 
  673.  
  674. $first_field = $object_field; 
  675. $field_data = $object_field_opt; 
  676. $field_type = 'object_field'; 
  677.  
  678. break; 
  679.  
  680. // Simple fields have no other output options 
  681. if ( 'pick' == $field_data[ 'type' ] && in_array( $field_data[ 'pick_object' ], $simple_tableless_objects ) ) { 
  682. $params->output = 'arrays'; 
  683.  
  684. if ( empty( $value ) && in_array( $field_data[ 'type' ], $tableless_field_types ) ) { 
  685. $params->raw = true; 
  686.  
  687. $value = false; 
  688.  
  689. if ( 'arrays' != $params->output && isset( $this->row[ '_' . $params->output . '_' . $params->name ] ) ) { 
  690. $value = $this->row[ '_' . $params->output . '_' . $params->name ]; 
  691. elseif ( 'arrays' == $params->output && isset( $this->row[ $params->name ] ) ) { 
  692. $value = $this->row[ $params->name ]; 
  693.  
  694. if ( false !== $value && !is_array( $value ) && 'pick' == $field_data[ 'type' ] && in_array( $field_data[ 'pick_object' ], $simple_tableless_objects ) ) 
  695. $value = PodsForm::field_method( 'pick', 'simple_value', $params->name, $value, $field_data, $this->pod_data, $this->id(), true ); 
  696.  
  697. if ( empty( $value ) && isset( $this->row[ $params->name ] ) && ( !in_array( $field_data[ 'type' ], $tableless_field_types ) || 'arrays' == $params->output ) ) { 
  698. if ( empty( $field_data ) || in_array( $field_data[ 'type' ], array( 'boolean', 'number', 'currency' ) ) ) 
  699. $params->raw = true; 
  700.  
  701. if ( null === $params->single ) { 
  702. if ( isset( $this->fields[ $params->name ] ) && !in_array( $this->fields[ $params->name ][ 'type' ], $tableless_field_types ) ) 
  703. $params->single = true; 
  704. else 
  705. $params->single = false; 
  706.  
  707. $value = $this->row[ $params->name ]; 
  708. elseif ( empty( $value ) ) { 
  709. $object_field_found = false; 
  710.  
  711. if ( 'object_field' == $field_type ) { 
  712. $object_field_found = true; 
  713.  
  714. if ( isset( $this->row[ $first_field ] ) ) 
  715. $value = $this->row[ $first_field ]; 
  716. elseif ( in_array( $field_data[ 'type' ], $tableless_field_types ) ) { 
  717. $this->fields[ $first_field ] = $field_data; 
  718.  
  719. $object_field_found = false; 
  720. else 
  721. return null; 
  722.  
  723. if ( 'post_type' == $this->pod_data[ 'type' ] && !isset( $this->fields[ $params->name ] ) ) { 
  724. if ( !isset( $this->fields[ 'post_thumbnail' ] ) && ( 'post_thumbnail' == $params->name || 0 === strpos( $params->name, 'post_thumbnail.' ) ) ) { 
  725. $size = 'thumbnail'; 
  726.  
  727. if ( 0 === strpos( $params->name, 'post_thumbnail.' ) ) { 
  728. $field_names = explode( '.', $params->name ); 
  729.  
  730. if ( isset( $field_names[ 1 ] ) ) 
  731. $size = $field_names[ 1 ]; 
  732.  
  733. // Pods will auto-get the thumbnail ID if this isn't an attachment 
  734. $value = pods_image( $this->id(), $size, 0, null, true ); 
  735.  
  736. $object_field_found = true; 
  737. elseif ( !isset( $this->fields[ 'post_thumbnail_url' ] ) && ( 'post_thumbnail_url' == $params->name || 0 === strpos( $params->name, 'post_thumbnail_url.' ) ) ) { 
  738. $size = 'thumbnail'; 
  739.  
  740. if ( 0 === strpos( $params->name, 'post_thumbnail_url.' ) ) { 
  741. $field_names = explode( '.', $params->name ); 
  742.  
  743. if ( isset( $field_names[ 1 ] ) ) 
  744. $size = $field_names[ 1 ]; 
  745.  
  746. // Pods will auto-get the thumbnail ID if this isn't an attachment 
  747. $value = pods_image_url( $this->id(), $size, 0, true ); 
  748.  
  749. $object_field_found = true; 
  750. elseif ( 0 === strpos( $params->name, 'image_attachment.' ) ) { 
  751. $size = 'thumbnail'; 
  752.  
  753. $image_id = 0; 
  754.  
  755. $field_names = explode( '.', $params->name ); 
  756.  
  757. if ( isset( $field_names[ 1 ] ) ) 
  758. $image_id = $field_names[ 1 ]; 
  759.  
  760. if ( isset( $field_names[ 2 ] ) ) 
  761. $size = $field_names[ 2 ]; 
  762.  
  763. if ( !empty( $image_id ) ) { 
  764. $value = pods_image( $image_id, $size, 0, null, true ); 
  765.  
  766. if ( !empty( $value ) ) 
  767. $object_field_found = true; 
  768. elseif ( 0 === strpos( $params->name, 'image_attachment_url.' ) ) { 
  769. $size = 'thumbnail'; 
  770.  
  771. $image_id = 0; 
  772.  
  773. $field_names = explode( '.', $params->name ); 
  774.  
  775. if ( isset( $field_names[ 1 ] ) ) 
  776. $image_id = $field_names[ 1 ]; 
  777.  
  778. if ( isset( $field_names[ 2 ] ) ) 
  779. $size = $field_names[ 2 ]; 
  780.  
  781. if ( !empty( $image_id ) ) { 
  782. $value = pods_image_url( $image_id, $size, 0, true ); 
  783.  
  784. if ( !empty( $value ) ) 
  785. $object_field_found = true; 
  786. elseif ( 'user' == $this->pod_data[ 'type' ] && !isset( $this->fields[ $params->name ] ) ) { 
  787. if ( !isset( $this->fields[ 'avatar' ] ) && ( 'avatar' == $params->name || 0 === strpos( $params->name, 'avatar.' ) ) ) { 
  788. $size = null; 
  789.  
  790. if ( 0 === strpos( $params->name, 'avatar.' ) ) { 
  791. $field_names = explode( '.', $params->name ); 
  792.  
  793. if ( isset( $field_names[ 1 ] ) ) 
  794. $size = (int) $field_names[ 1 ]; 
  795.  
  796. if ( !empty( $size ) ) 
  797. $value = get_avatar( $this->id(), $size ); 
  798. else 
  799. $value = get_avatar( $this->id() ); 
  800.  
  801. $object_field_found = true; 
  802. elseif ( 0 === strpos( $params->name, 'image_attachment.' ) ) { 
  803. $size = 'thumbnail'; 
  804.  
  805. $image_id = 0; 
  806.  
  807. $field_names = explode( '.', $params->name ); 
  808.  
  809. if ( isset( $field_names[ 1 ] ) ) 
  810. $image_id = $field_names[ 1 ]; 
  811.  
  812. if ( isset( $field_names[ 2 ] ) ) 
  813. $size = $field_names[ 2 ]; 
  814.  
  815. if ( !empty( $image_id ) ) { 
  816. $value = pods_image( $image_id, $size, 0, null, true ); 
  817.  
  818. if ( !empty( $value ) ) 
  819. $object_field_found = true; 
  820. elseif ( 0 === strpos( $params->name, 'image_attachment_url.' ) ) { 
  821. $size = 'thumbnail'; 
  822.  
  823. $image_id = 0; 
  824.  
  825. $field_names = explode( '.', $params->name ); 
  826.  
  827. if ( isset( $field_names[ 1 ] ) ) 
  828. $image_id = $field_names[ 1 ]; 
  829.  
  830. if ( isset( $field_names[ 2 ] ) ) 
  831. $size = $field_names[ 2 ]; 
  832.  
  833. if ( !empty( $image_id ) ) { 
  834. $value = pods_image_url( $image_id, $size, 0, true ); 
  835.  
  836. if ( !empty( $value ) ) 
  837. $object_field_found = true; 
  838.  
  839. if ( false === $object_field_found ) { 
  840. $params->traverse = array( $params->name ); 
  841.  
  842. if ( false !== strpos( $params->name, '.' ) ) { 
  843. $params->traverse = explode( '.', $params->name ); 
  844.  
  845. $params->name = $params->traverse[ 0 ]; 
  846.  
  847. if ( isset( $this->fields[ $params->name ] ) && isset( $this->fields[ $params->name ][ 'type' ] ) ) { 
  848. /** 
  849. * Modify value returned by field() after its retrieved, but before its validated or formatted 
  850. * Filter name is set dynamically with name of field: "pods_pods_field_{field_name}" 
  851. * @since unknown 
  852. * @param array|string|null $value Value retrieved. 
  853. * @param array|object $row Current row being outputted. 
  854. * @param array $params Params array passed to field(). 
  855. * @param object|Pods $this Current Pods object. 
  856. */ 
  857. $v = apply_filters( 'pods_pods_field_' . $this->fields[ $params->name ][ 'type' ], null, $this->fields[ $params->name ], $this->row, $params, $this ); 
  858.  
  859. if ( null !== $v ) 
  860. return $v; 
  861.  
  862. $simple = false; 
  863. $simple_data = array(); 
  864.  
  865. if ( isset( $this->fields[ $params->name ] ) ) { 
  866. if ( 'meta' == $this->pod_data[ 'storage' ] ) { 
  867. if ( !in_array( $this->fields[ $params->name ][ 'type' ], $tableless_field_types ) ) 
  868. $simple = true; 
  869.  
  870. if ( in_array( $this->fields[ $params->name ][ 'type' ], $tableless_field_types ) ) { 
  871. $params->raw = true; 
  872.  
  873. if ( 'pick' == $this->fields[ $params->name ][ 'type' ] && in_array( $this->fields[ $params->name ][ 'pick_object' ], $simple_tableless_objects ) ) { 
  874. $simple = true; 
  875. $params->single = true; 
  876. elseif ( in_array( $this->fields[ $params->name ][ 'type' ], array( 'boolean', 'number', 'currency' ) ) ) 
  877. $params->raw = true; 
  878.  
  879. if ( !isset( $this->fields[ $params->name ] ) || !in_array( $this->fields[ $params->name ][ 'type' ], $tableless_field_types ) || $simple ) { 
  880. if ( null === $params->single ) { 
  881. if ( isset( $this->fields[ $params->name ] ) && !in_array( $this->fields[ $params->name ][ 'type' ], $tableless_field_types ) ) 
  882. $params->single = true; 
  883. else 
  884. $params->single = false; 
  885.  
  886. $no_conflict = pods_no_conflict_check( $this->pod_data[ 'type' ] ); 
  887.  
  888. if ( !$no_conflict ) 
  889. pods_no_conflict_on( $this->pod_data[ 'type' ] ); 
  890.  
  891. if ( in_array( $this->pod_data[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment' ) ) ) { 
  892. $id = $this->id(); 
  893.  
  894. $metadata_type = $this->pod_data['type']; 
  895.  
  896. if ( in_array( $this->pod_data[ 'type' ], array( 'post_type', 'media' ) ) ) { 
  897. $metadata_type = 'post'; 
  898.  
  899. // Support for WPML 'duplicated' translation handling 
  900. if ( is_object( $sitepress ) && $sitepress->is_translated_post_type( $this->pod_data[ 'name' ] ) ) { 
  901. $master_post_id = (int) get_metadata( $metadata_type, $id, '_icl_lang_duplicate_of', true ); 
  902.  
  903. if ( 0 < $master_post_id ) 
  904. $id = $master_post_id; 
  905. } elseif ( 'taxonomy' == $this->pod_data[ 'type' ] ) { 
  906. $metadata_type = 'term'; 
  907.  
  908. $value = get_metadata( $metadata_type, $id, $params->name, $params->single ); 
  909.  
  910. $single_multi = 'single'; 
  911.  
  912. if ( isset( $this->fields[ $params->name ] ) ) { 
  913. $single_multi = pods_v( $this->fields[ $params->name ][ 'type' ] . '_format_type', $this->fields[ $params->name ][ 'options' ], 'single' ); 
  914.  
  915. if ( $simple && !is_array( $value ) && 'single' != $single_multi ) { 
  916. $value = get_metadata( $metadata_type, $id, $params->name ); 
  917. elseif ( 'settings' == $this->pod_data[ 'type' ] ) 
  918. $value = get_option( $this->pod_data[ 'name' ] . '_' . $params->name, null ); 
  919.  
  920. // Handle Simple Relationships 
  921. if ( $simple ) { 
  922. if ( null === $params->single ) 
  923. $params->single = false; 
  924.  
  925.  
  926. $value = PodsForm::field_method( 'pick', 'simple_value', $params->name, $value, $this->fields[ $params->name ], $this->pod_data, $this->id(), true ); 
  927.  
  928. if ( !$no_conflict ) 
  929. pods_no_conflict_off( $this->pod_data[ 'type' ] ); 
  930. else { 
  931. // Dot-traversal 
  932. $pod = $this->pod; 
  933. $ids = array( $this->id() ); 
  934. $all_fields = array(); 
  935.  
  936. $lookup = $params->traverse; 
  937.  
  938. // Get fields matching traversal names 
  939. if ( !empty( $lookup ) ) { 
  940. $fields = $this->api->load_fields( array( 
  941. 'name' => $lookup,  
  942. 'type' => $tableless_field_types,  
  943. 'object_fields' => true // @todo support object fields too 
  944. ) ); 
  945.  
  946. if ( !empty( $fields ) ) { 
  947. foreach ( $fields as $field ) { 
  948. if ( !empty( $field ) ) { 
  949. if ( !isset( $all_fields[ $field[ 'pod' ] ] ) ) 
  950. $all_fields[ $field[ 'pod' ] ] = array(); 
  951.  
  952. $all_fields[ $field[ 'pod' ] ][ $field[ 'name' ] ] = $field; 
  953.  
  954. if ( !empty( $this->pod_data[ 'object_fields' ] ) ) { 
  955. foreach ( $this->pod_data[ 'object_fields' ] as $object_field => $object_field_opt ) { 
  956. if ( in_array( $object_field_opt[ 'type' ], $tableless_field_types ) ) { 
  957. $all_fields[ $this->pod ][ $object_field ] = $object_field_opt; 
  958.  
  959. $last_type = $last_object = $last_pick_val = ''; 
  960. $last_options = array(); 
  961.  
  962. $single_multi = pods_v( $this->fields[ $params->name ][ 'type' ] . '_format_type', $this->fields[ $params->name ][ 'options' ], 'single' ); 
  963.  
  964. if ( 'multi' == $single_multi ) 
  965. $limit = (int) pods_v( $this->fields[ $params->name ][ 'type' ] . '_limit', $this->fields[ $params->name ][ 'options' ], 0 ); 
  966. else 
  967. $limit = 1; 
  968.  
  969. $last_limit = 0; 
  970.  
  971. // Loop through each traversal level 
  972. foreach ( $params->traverse as $key => $field ) { 
  973. $last_loop = false; 
  974.  
  975. if ( count( $params->traverse ) <= ( $key + 1 ) ) 
  976. $last_loop = true; 
  977.  
  978. $field_exists = isset( $all_fields[ $pod ][ $field ] ); 
  979.  
  980. $simple = false; 
  981. $last_options = array(); 
  982.  
  983. if ( $field_exists && 'pick' == $all_fields[ $pod ][ $field ][ 'type' ] && in_array( $all_fields[ $pod ][ $field ][ 'pick_object' ], $simple_tableless_objects ) ) { 
  984. $simple = true; 
  985. $last_options = $all_fields[ $pod ][ $field ]; 
  986.  
  987. // Tableless handler 
  988. if ( $field_exists && ( !in_array( $all_fields[ $pod ][ $field ][ 'type' ], array( 'pick', 'taxonomy' ) ) || !$simple ) ) { 
  989. $type = $all_fields[ $pod ][ $field ][ 'type' ]; 
  990. $pick_object = $all_fields[ $pod ][ $field ][ 'pick_object' ]; 
  991. $pick_val = $all_fields[ $pod ][ $field ][ 'pick_val' ]; 
  992.  
  993. if ( 'table' == $pick_object ) { 
  994. $pick_val = pods_v( 'pick_table', $all_fields[ $pod ][ $field ][ 'options' ], $pick_val, true ); 
  995. elseif ( '__current__' == $pick_val ) { 
  996. $pick_val = $pod; 
  997.  
  998. $last_limit = 0; 
  999.  
  1000. if ( in_array( $type, $tableless_field_types ) ) { 
  1001. $single_multi = pods_v( "{$type}_format_type", $all_fields[ $pod ][ $field ][ 'options' ], 'single' ); 
  1002.  
  1003. if ( 'multi' == $single_multi ) { 
  1004. $last_limit = (int) pods_v( "{$type}_limit", $all_fields[ $pod ][ $field ][ 'options' ], 0 ); 
  1005. else { 
  1006. $last_limit = 1; 
  1007.  
  1008. $last_type = $type; 
  1009. $last_object = $pick_object; 
  1010. $last_pick_val = $pick_val; 
  1011. $last_options = $all_fields[ $pod ][ $field ]; 
  1012.  
  1013. // Temporary hack until there's some better handling here 
  1014. $last_limit = $last_limit * count( $ids ); 
  1015.  
  1016. // Get related IDs 
  1017. if ( !isset( $all_fields[ $pod ][ $field ][ 'pod_id' ] ) ) { 
  1018. $all_fields[ $pod ][ $field ][ 'pod_id' ] = 0; 
  1019.  
  1020. if ( isset( $all_fields[ $pod ][ $field ][ 'id' ] ) ) { 
  1021. $ids = $this->api->lookup_related_items( 
  1022. $all_fields[ $pod ][ $field ][ 'id' ],  
  1023. $all_fields[ $pod ][ $field ][ 'pod_id' ],  
  1024. $ids,  
  1025. $all_fields[ $pod ][ $field ] 
  1026. ); 
  1027.  
  1028. // No items found 
  1029. if ( empty( $ids ) ) { 
  1030. return false; 
  1031. } // @todo This should return array() if not $params->single 
  1032. elseif ( 0 < $last_limit ) { 
  1033. $ids = array_slice( $ids, 0, $last_limit ); 
  1034.  
  1035. // Get $pod if related to a Pod 
  1036. if ( !empty( $pick_object ) && ( !empty( $pick_val ) || in_array( $pick_object, array( 'user', 'media', 'comment' ) ) ) ) { 
  1037. if ( 'pod' == $pick_object ) { 
  1038. $pod = $pick_val; 
  1039. else { 
  1040. $check = $this->api->get_table_info( $pick_object, $pick_val ); 
  1041.  
  1042. if ( !empty( $check ) && !empty( $check[ 'pod' ] ) ) { 
  1043. $pod = $check[ 'pod' ][ 'name' ]; 
  1044. // Assume last iteration 
  1045. else { 
  1046. // Invalid field 
  1047. if ( 0 == $key ) { 
  1048. return false; 
  1049.  
  1050. $last_loop = true; 
  1051.  
  1052. if ( $last_loop ) { 
  1053. $object_type = $last_object; 
  1054. $object = $last_pick_val; 
  1055.  
  1056. if ( in_array( $last_type, PodsForm::file_field_types() ) ) { 
  1057. $object_type = 'media'; 
  1058. $object = 'attachment'; 
  1059.  
  1060. $data = array(); 
  1061.  
  1062. $table = $this->api->get_table_info( $object_type, $object, null, null, $last_options ); 
  1063.  
  1064. $join = $where = array(); 
  1065.  
  1066. if ( !empty( $table[ 'join' ] ) ) 
  1067. $join = (array) $table[ 'join' ]; 
  1068.  
  1069. if ( !empty( $table[ 'where' ] ) || !empty( $ids ) ) { 
  1070. foreach ( $ids as $id ) { 
  1071. $where[ $id ] = '`t`.`' . $table[ 'field_id' ] . '` = ' . (int) $id; 
  1072.  
  1073. if ( !empty( $where ) ) { 
  1074. $where = array( implode( ' OR ', $where ) ); 
  1075.  
  1076. if ( !empty( $table[ 'where' ] ) ) { 
  1077. $where = array_merge( $where, array_values( (array) $table[ 'where' ] ) ); 
  1078.  
  1079. /** 
  1080. * @var $related_obj Pods 
  1081. */ 
  1082. $related_obj = false; 
  1083.  
  1084. if ( 'pod' == $object_type ) 
  1085. $related_obj = pods( $object, null, false ); 
  1086. elseif ( !empty( $table[ 'pod' ] ) ) 
  1087. $related_obj = pods( $table[ 'pod' ][ 'name' ], null, false ); 
  1088.  
  1089. if ( !empty( $table[ 'table' ] ) || !empty( $related_obj ) ) { 
  1090. $sql = array( 
  1091. 'select' => '*, `t`.`' . $table[ 'field_id' ] . '` AS `pod_item_id`',  
  1092. 'table' => $table[ 'table' ],  
  1093. 'join' => $join,  
  1094. 'where' => $where,  
  1095. 'orderby' => $params->orderby,  
  1096. 'pagination' => false,  
  1097. 'search' => false,  
  1098. 'limit' => -1,  
  1099. 'expires' => 180 // @todo This could potentially cause issues if someone changes the data within this time and persistent storage is used 
  1100. ); 
  1101.  
  1102. // Output types 
  1103. if ( in_array( $params->output, array( 'ids', 'objects', 'pods' ) ) ) 
  1104. $sql[ 'select' ] = '`t`.`' . $table[ 'field_id' ] . '` AS `pod_item_id`'; 
  1105. elseif ( 'names' == $params->output && !empty( $table[ 'field_index' ] ) ) 
  1106. $sql[ 'select' ] = '`t`.`' . $table[ 'field_index' ] . '` AS `pod_item_index`, `t`.`' . $table[ 'field_id' ] . '` AS `pod_item_id`'; 
  1107.  
  1108. if ( !empty( $params->params ) && is_array( $params->params ) ) { 
  1109. $where = $sql[ 'where' ]; 
  1110.  
  1111. $sql = array_merge( $sql, $params->params ); 
  1112.  
  1113. if ( isset( $params->params[ 'where' ] ) ) 
  1114. $sql[ 'where' ] = array_merge( (array) $where, (array) $params->params['where' ] ); 
  1115.  
  1116. if ( empty( $related_obj ) ) { 
  1117. if ( !is_object( $this->alt_data ) ) 
  1118. $this->alt_data = pods_data( null, 0, true, true ); 
  1119.  
  1120. $item_data = $this->alt_data->select( $sql ); 
  1121. else 
  1122. $item_data = $related_obj->find( $sql )->data(); 
  1123.  
  1124. $items = array(); 
  1125.  
  1126. if ( !empty( $item_data ) ) { 
  1127. foreach ( $item_data as $item ) { 
  1128. if ( is_array( $item ) ) 
  1129. $item = (object) $item; 
  1130.  
  1131. if ( empty( $item->pod_item_id ) ) 
  1132. continue; 
  1133.  
  1134. // Bypass pass field 
  1135. if ( isset( $item->user_pass ) ) 
  1136. unset( $item->user_pass ); 
  1137.  
  1138. // Get Item ID 
  1139. $item_id = $item->pod_item_id; 
  1140.  
  1141. // Output types 
  1142. if ( 'ids' == $params->output ) 
  1143. $item = (int) $item_id; 
  1144. elseif ( 'names' == $params->output && !empty( $table[ 'field_index' ] ) ) 
  1145. $item = $item->pod_item_index; 
  1146. elseif ( 'objects' == $params->output ) { 
  1147. if ( in_array( $object_type, array( 'post_type', 'media' ) ) ) 
  1148. $item = get_post( $item_id ); 
  1149. elseif ( 'taxonomy' == $object_type ) 
  1150. $item = get_term( $item_id, $object ); 
  1151. elseif ( 'user' == $object_type ) { 
  1152. $item = get_userdata( $item_id ); 
  1153.  
  1154. if ( !empty( $item ) ) { 
  1155. // Get other vars 
  1156. $roles = $item->roles; 
  1157. $caps = $item->caps; 
  1158. $allcaps = $item->allcaps; 
  1159.  
  1160. $item = $item->data; 
  1161.  
  1162. // Set other vars 
  1163. $item->roles = $roles; 
  1164. $item->caps = $caps; 
  1165. $item->allcaps = $allcaps; 
  1166.  
  1167. unset( $item->user_pass ); 
  1168. elseif ( 'comment' == $object_type ) 
  1169. $item = get_comment( $item_id ); 
  1170. else 
  1171. $item = (object) $item; 
  1172. elseif ( 'pods' == $params->output ) { 
  1173. $item = pods( $object, (int) $item_id ); 
  1174. else // arrays 
  1175. $item = get_object_vars( (object) $item ); 
  1176.  
  1177. // Pass item data into $data 
  1178. $items[ $item_id ] = $item; 
  1179.  
  1180. // Cleanup 
  1181. unset( $item_data ); 
  1182.  
  1183. // Return all of the data in the order expected 
  1184. if ( empty( $params->orderby ) ) { 
  1185. foreach ( $ids as $id ) { 
  1186. if ( isset( $items[ $id ] ) ) { 
  1187. $data[ $id ] = $items[ $id ]; 
  1188. } else { 
  1189. // Use order set by orderby 
  1190. foreach ( $items as $id => $v ) { 
  1191. if ( in_array( $id, $ids ) ) { 
  1192. $data[ $id ] = $v; 
  1193.  
  1194. if ( in_array( $last_type, $tableless_field_types ) || in_array( $last_type, array( 'boolean', 'number', 'currency' ) ) ) 
  1195. $params->raw = true; 
  1196.  
  1197. if ( empty( $data ) ) 
  1198. $value = false; 
  1199. else { 
  1200. $object_type = $table[ 'type' ]; 
  1201.  
  1202. if ( in_array( $table[ 'type' ], array( 'post_type', 'attachment', 'media' ) ) ) 
  1203. $object_type = 'post'; 
  1204.  
  1205. $no_conflict = true; 
  1206.  
  1207. if ( in_array( $object_type, array( 'post', 'taxonomy', 'user', 'comment', 'settings' ) ) ) { 
  1208. $no_conflict = pods_no_conflict_check( $object_type ); 
  1209.  
  1210. if ( !$no_conflict ) 
  1211. pods_no_conflict_on( $object_type ); 
  1212.  
  1213. // Return entire array 
  1214. if ( false !== $field_exists && ( in_array( $last_type, $tableless_field_types ) && !$simple ) ) 
  1215. $value = $data; 
  1216. // Return an array of single column values 
  1217. else { 
  1218. $value = array(); 
  1219.  
  1220. foreach ( $data as $item_id => $item ) { 
  1221. // $field is 123x123, needs to be _src.123x123 
  1222. $full_field = implode( '.', array_splice( $params->traverse, $key ) ); 
  1223.  
  1224. if ( is_array( $item ) && isset( $item[ $field ] ) ) { 
  1225. if ( $table[ 'field_id' ] == $field ) 
  1226. $value[] = (int) $item[ $field ]; 
  1227. else 
  1228. $value[] = $item[ $field ]; 
  1229. elseif ( is_object( $item ) && isset( $item->{$field} ) ) { 
  1230. if ( $table[ 'field_id' ] == $field ) 
  1231. $value[] = (int) $item->{$field}; 
  1232. else 
  1233. $value[] = $item->{$field}; 
  1234. elseif ( ( ( false !== strpos( $full_field, '_src' ) || 'guid' == $field ) && ( in_array( $table[ 'type' ], array( 'attachment', 'media' ) ) || in_array( $last_type, PodsForm::file_field_types() ) ) ) || ( in_array( $field, array( '_link', 'detail_url' ) ) || in_array( $field, array( 'permalink', 'the_permalink' ) ) && in_array( $last_type, PodsForm::file_field_types() ) ) ) { 
  1235. $size = 'full'; 
  1236.  
  1237. if ( false !== strpos( $full_field, '_src.' ) && 5 < strlen( $full_field ) ) 
  1238. $size = substr( $full_field, 5 ); 
  1239. elseif ( false !== strpos( $full_field, '_src_relative.' ) && 14 < strlen( $full_field ) ) 
  1240. $size = substr( $full_field, 14 ); 
  1241. elseif ( false !== strpos( $full_field, '_src_schemeless.' ) && 16 < strlen( $full_field ) ) 
  1242. $size = substr( $full_field, 16 ); 
  1243.  
  1244. $value_url = pods_image_url( $item_id, $size ); 
  1245.  
  1246. if ( false !== strpos( $full_field, '_src_relative' ) && !empty( $value_url ) ) { 
  1247. $value_url_parsed = parse_url( $value_url ); 
  1248. $value_url = $value_url_parsed[ 'path' ]; 
  1249. elseif ( false !== strpos( $full_field, '_src_schemeless' ) && !empty( $value_url ) ) 
  1250. $value_url = str_replace( array( 'http://', 'https://' ), '//', $value_url ); 
  1251.  
  1252. if ( !empty( $value_url ) ) 
  1253. $value[] = $value_url; 
  1254.  
  1255. $params->raw_display = true; 
  1256. elseif ( false !== strpos( $full_field, '_img' ) && ( in_array( $table[ 'type' ], array( 'attachment', 'media' ) ) || in_array( $last_type, PodsForm::file_field_types() ) ) ) { 
  1257. $size = 'full'; 
  1258.  
  1259. if ( false !== strpos( $full_field, '_img.' ) && 5 < strlen( $full_field ) ) 
  1260. $size = substr( $full_field, 5 ); 
  1261.  
  1262. $value[] = pods_image( $item_id, $size ); 
  1263.  
  1264. $params->raw_display = true; 
  1265. elseif ( in_array( $field, array( '_link', 'detail_url' ) ) || in_array( $field, array( 'permalink', 'the_permalink' ) ) ) { 
  1266. if ( 'pod' == $object_type ) { 
  1267. if ( is_object( $related_obj ) ) { 
  1268. $related_obj->fetch( $item_id ); 
  1269.  
  1270. $value[] = $related_obj->field( 'detail_url' ); 
  1271. else 
  1272. $value[] = ''; 
  1273. elseif ( 'post' == $object_type ) 
  1274. $value[] = get_permalink( $item_id ); 
  1275. elseif ( 'taxonomy' == $object_type ) 
  1276. $value[] = get_term_link( $item_id, $object ); 
  1277. elseif ( 'user' == $object_type ) 
  1278. $value[] = get_author_posts_url( $item_id ); 
  1279. elseif ( 'comment' == $object_type ) 
  1280. $value[] = get_comment_link( $item_id ); 
  1281. else 
  1282. $value[] = ''; 
  1283.  
  1284. $params->raw_display = true; 
  1285. elseif ( in_array( $object_type, array( 'post', 'taxonomy', 'user', 'comment' ) ) ) { 
  1286. $metadata_object_id = $item_id; 
  1287.  
  1288. $metadata_type = $object_type; 
  1289.  
  1290. if ( 'post' == $object_type ) { 
  1291. // Support for WPML 'duplicated' translation handling 
  1292. if ( is_object( $sitepress ) && $sitepress->is_translated_post_type( $object ) ) { 
  1293. $master_post_id = (int) get_metadata( $metadata_type, $metadata_object_id, '_icl_lang_duplicate_of', true ); 
  1294.  
  1295. if ( 0 < $master_post_id ) 
  1296. $metadata_object_id = $master_post_id; 
  1297. } elseif ( 'taxonomy' == $object_type ) { 
  1298. $metadata_type = 'term'; 
  1299.  
  1300. $value[] = get_metadata( $metadata_type, $metadata_object_id, $field, true ); 
  1301. elseif ( 'settings' == $object_type ) 
  1302. $value[] = get_option( $object . '_' . $field ); 
  1303.  
  1304. if ( in_array( $object_type, array( 'post', 'taxonomy', 'user', 'comment', 'settings' ) ) && !$no_conflict ) 
  1305. pods_no_conflict_off( $object_type ); 
  1306.  
  1307. // Handle Simple Relationships 
  1308. if ( $simple ) { 
  1309. if ( null === $params->single ) 
  1310. $params->single = false; 
  1311.  
  1312. $value = PodsForm::field_method( 'pick', 'simple_value', $field, $value, $last_options, $all_fields[ $pod ], 0, true ); 
  1313. elseif ( false === $params->in_form && !empty( $value ) ) 
  1314. $value = array_values( $value ); 
  1315.  
  1316. // Return a single column value 
  1317. if ( false === $params->in_form && 1 == $limit && !empty( $value ) && is_array( $value ) && 1 == count( $value ) ) 
  1318. $value = current( $value ); 
  1319.  
  1320. if ( $last_options ) { 
  1321. $last_field_data = $last_options; 
  1322.  
  1323. break; 
  1324.  
  1325. if ( !empty( $params->traverse ) && 1 < count( $params->traverse ) ) { 
  1326. $field_names = implode( '.', $params->traverse ); 
  1327.  
  1328. $this->row[ $field_names ] = $value; 
  1329. elseif ( 'arrays' != $params->output && in_array( $field_data[ 'type' ], $tableless_field_types ) ) { 
  1330. $this->row[ '_' . $params->output . '_' . $params->full_name ] = $value; 
  1331. elseif ( 'arrays' == $params->output || !in_array( $field_data[ 'type' ], $tableless_field_types ) ) { 
  1332. $this->row[ $params->full_name ] = $value; 
  1333.  
  1334. if ( $params->single && is_array( $value ) && 1 == count( $value ) ) 
  1335. $value = current( $value ); 
  1336.  
  1337. if ( ! empty( $last_field_data ) ) { 
  1338. $field_data = $last_field_data; 
  1339.  
  1340. // @todo Expand this into traversed fields too 
  1341. if ( !empty( $field_data ) && ( $params->display || !$params->raw ) && !$params->in_form && !$params->raw_display ) { 
  1342. if ( $params->display || ( ( $params->get_meta || $params->deprecated ) && !in_array( $field_data[ 'type' ], $tableless_field_types ) ) ) { 
  1343. $field_data[ 'options' ] = pods_var_raw( 'options', $field_data, array(), null, true ); 
  1344.  
  1345. $post_temp = false; 
  1346.  
  1347. if ( 'post_type' == pods_v( 'type', $this->pod_data ) && 0 < $this->id() && ( !isset( $GLOBALS[ 'post' ] ) || empty( $GLOBALS[ 'post' ] ) ) ) { 
  1348. global $post_ID, $post; 
  1349.  
  1350. $post_temp = true; 
  1351.  
  1352. $old_post = $GLOBALS[ 'post' ]; 
  1353. $old_ID = $GLOBALS[ 'post_ID' ]; 
  1354.  
  1355. $post = get_post( $this->id() ); 
  1356. $post_ID = $this->id(); 
  1357.  
  1358. $filter = pods_var_raw( 'display_filter', $field_data[ 'options' ] ); 
  1359.  
  1360. if ( 0 < strlen( $filter ) ) { 
  1361. $args = array( 
  1362. $filter,  
  1363. $value 
  1364. ); 
  1365.  
  1366. $filter_args = pods_var_raw( 'display_filter_args', $field_data[ 'options' ] ); 
  1367.  
  1368. if ( !empty( $filter_args ) ) 
  1369. $args = array_merge( $args, compact( $filter_args ) ); 
  1370.  
  1371. $value = call_user_func_array( 'apply_filters', $args ); 
  1372. elseif ( 1 == pods_v( 'display_process', $field_data[ 'options' ], 1 ) ) { 
  1373. $value = PodsForm::display( 
  1374. $field_data[ 'type' ],  
  1375. $value,  
  1376. $params->name,  
  1377. array_merge( $field_data, $field_data[ 'options' ] ),  
  1378. $this->pod_data,  
  1379. $this->id() 
  1380. ); 
  1381.  
  1382. if ( $post_temp ) { 
  1383. $post = $old_post; 
  1384. $post_ID = $old_ID; 
  1385. else { 
  1386. $value = PodsForm::value( 
  1387. $field_data[ 'type' ],  
  1388. $value,  
  1389. $params->name,  
  1390. array_merge( $field_data, $field_data[ 'options' ] ),  
  1391. $this->pod_data,  
  1392. $this->id() 
  1393. ); 
  1394.  
  1395. /** 
  1396. * Modify value returned by field() directly before output. 
  1397. * Will not run if value was null 
  1398. * @since unknown 
  1399. * @param array|string|null $value Value to be returned. 
  1400. * @param array|object $row Current row being outputted. 
  1401. * @param array $params Params array passed to field(). 
  1402. * @param object|Pods $this Current Pods object. 
  1403. */ 
  1404. $value = apply_filters( 'pods_pods_field', $value, $this->row, $params, $this ); 
  1405.  
  1406. return $value; 
  1407.  
  1408. /** 
  1409. * Check if an item field has a specific value in it 
  1410. * @param string $field Field name 
  1411. * @param mixed $value Value to check 
  1412. * @param int $id (optional) ID of the pod item to check 
  1413. * @return bool Whether the value was found 
  1414. * @since 2.3.3 
  1415. */ 
  1416. public function has ( $field, $value, $id = null ) { 
  1417. $pod =& $this; 
  1418.  
  1419. if ( null === $id ) 
  1420. $id = $this->id(); 
  1421. elseif ( $id != $this->id() ) 
  1422. $pod = pods( $this->pod, $id ); 
  1423.  
  1424. $this->do_hook( 'has', $field, $value, $id ); 
  1425.  
  1426. if ( !isset( $this->fields[ $field ] ) ) 
  1427. return false; 
  1428.  
  1429. // Tableless fields 
  1430. if ( in_array( $this->fields[ $field ][ 'type' ], PodsForm::tableless_field_types() ) ) { 
  1431. if ( !is_array( $value ) ) 
  1432. $value = explode( ', ', $value ); 
  1433.  
  1434. if ( 'pick' == $this->fields[ $field ][ 'type' ] && in_array( $this->fields[ $field ][ 'pick_object' ], PodsForm::simple_tableless_objects() ) ) { 
  1435. $current_value = $pod->raw( $field ); 
  1436.  
  1437. if ( !empty( $current_value ) ) 
  1438. $current_value = (array) $current_value; 
  1439.  
  1440. foreach ( $current_value as $v ) { 
  1441. if ( in_array( $v, $value ) ) 
  1442. return true; 
  1443. else { 
  1444. $related_ids = $this->api->lookup_related_items( $this->fields[ $field ][ 'id' ], $this->pod_data[ 'id' ], $id, $this->fields[ $field ], $this->pod_data ); 
  1445.  
  1446. foreach ( $value as $k => $v ) { 
  1447. if ( !preg_match( '/[^0-9]/', $v ) ) 
  1448. $value[ $k ] = (int) $v; 
  1449. // @todo Convert slugs into IDs 
  1450. else { 
  1451.  
  1452.  
  1453. foreach ( $related_ids as $v ) { 
  1454. if ( in_array( $v, $value ) ) 
  1455. return true; 
  1456. // Text fields 
  1457. elseif ( in_array( $this->fields[ $field ][ 'type' ], PodsForm::text_field_types() ) ) { 
  1458. $current_value = $pod->raw( $field ); 
  1459.  
  1460. if ( 0 < strlen( $current_value ) ) 
  1461. return stripos( $current_value, $value ); 
  1462. // All other fields 
  1463. else 
  1464. return $this->is( $field, $value, $id ); 
  1465.  
  1466. return false; 
  1467.  
  1468. /** 
  1469. * Check if an item field is a specific value 
  1470. * @param string $field Field name 
  1471. * @param mixed $value Value to check 
  1472. * @param int $id (optional) ID of the pod item to check 
  1473. * @return bool Whether the value was found 
  1474. * @since 2.3.3 
  1475. */ 
  1476. public function is ( $field, $value, $id = null ) { 
  1477. $pod =& $this; 
  1478.  
  1479. if ( null === $id ) 
  1480. $id = $this->id(); 
  1481. elseif ( $id != $this->id() ) 
  1482. $pod = pods( $this->pod, $id ); 
  1483.  
  1484. $this->do_hook( 'is', $field, $value, $id ); 
  1485.  
  1486. if ( !isset( $this->fields[ $field ] ) ) 
  1487. return false; 
  1488.  
  1489. // Tableless fields 
  1490. if ( in_array( $this->fields[ $field ][ 'type' ], PodsForm::tableless_field_types() ) ) { 
  1491. if ( !is_array( $value ) ) 
  1492. $value = explode( ', ', $value ); 
  1493.  
  1494. $current_value = array(); 
  1495.  
  1496. if ( 'pick' == $this->fields[ $field ][ 'type' ] && in_array( $this->fields[ $field ][ 'pick_object' ], PodsForm::simple_tableless_objects() ) ) { 
  1497. $current_value = $pod->raw( $field ); 
  1498.  
  1499. if ( !empty( $current_value ) ) 
  1500. $current_value = (array) $current_value; 
  1501.  
  1502. foreach ( $current_value as $v ) { 
  1503. if ( in_array( $v, $value ) ) 
  1504. return true; 
  1505. else { 
  1506. $related_ids = $this->api->lookup_related_items( $this->fields[ $field ][ 'id' ], $this->pod_data[ 'id' ], $id, $this->fields[ $field ], $this->pod_data ); 
  1507.  
  1508. foreach ( $value as $k => $v ) { 
  1509. if ( !preg_match( '/[^0-9]/', $v ) ) 
  1510. $value[ $k ] = (int) $v; 
  1511. // @todo Convert slugs into IDs 
  1512. else { 
  1513.  
  1514.  
  1515. foreach ( $related_ids as $v ) { 
  1516. if ( in_array( $v, $value ) ) 
  1517. return true; 
  1518.  
  1519. if ( !empty( $current_value ) ) 
  1520. $current_value = array_filter( array_unique( $current_value ) ); 
  1521. else 
  1522. $current_value = array(); 
  1523.  
  1524. if ( !empty( $value ) ) 
  1525. $value = array_filter( array_unique( $value ) ); 
  1526. else 
  1527. $value = array(); 
  1528.  
  1529. sort( $current_value ); 
  1530. sort( $value ); 
  1531.  
  1532. if ( $value === $current_value ) 
  1533. return true; 
  1534. // Number fields 
  1535. elseif ( in_array( $this->fields[ $field ][ 'type' ], PodsForm::number_field_types() ) ) { 
  1536. $current_value = $pod->raw( $field ); 
  1537.  
  1538. if ( (float) $current_value === (float) $value ) 
  1539. return true; 
  1540. // Date fields 
  1541. elseif ( in_array( $this->fields[ $field ][ 'type' ], PodsForm::date_field_types() ) ) { 
  1542. $current_value = $pod->raw( $field ); 
  1543.  
  1544. if ( 0 < strlen( $current_value ) ) { 
  1545. if ( strtotime( $current_value ) == strtotime( $value ) ) 
  1546. return true; 
  1547. elseif ( empty( $value ) ) 
  1548. return true; 
  1549. // Text fields 
  1550. elseif ( in_array( $this->fields[ $field ][ 'type' ], PodsForm::text_field_types() ) ) { 
  1551. $current_value = $pod->raw( $field ); 
  1552.  
  1553. if ( (string) $current_value === (string) $value ) 
  1554. return true; 
  1555. // All other fields 
  1556. else { 
  1557. $current_value = $pod->raw( $field ); 
  1558.  
  1559. if ( $current_value === $value ) 
  1560. return true; 
  1561.  
  1562. return false; 
  1563.  
  1564. /** 
  1565. * Return the item ID 
  1566. * @return int 
  1567. * @since 2.0 
  1568. */ 
  1569. public function id () { 
  1570. if ( isset( $this->data->row ) && isset( $this->data->row[ 'id' ] ) ) { 
  1571. // If we already have data loaded return that ID 
  1572. return $this->data->row[ 'id' ]; 
  1573. return $this->field( $this->data->field_id ); 
  1574.  
  1575. /** 
  1576. * Return the previous item ID, loops at the last id to return the first 
  1577. * @param int $id 
  1578. * @param array $params_override 
  1579. * @return int 
  1580. * @since 2.0 
  1581. */ 
  1582. public function prev_id ( $id = null, $params_override = null ) { 
  1583. if ( null === $id ) 
  1584. $id = $this->id(); 
  1585.  
  1586. $id = (int) $id; 
  1587.  
  1588. $params = array( 
  1589. 'select' => "`t`.`{$this->data->field_id}`",  
  1590. 'where' => "`t`.`{$this->data->field_id}` < {$id}",  
  1591. 'orderby' => "`t`.`{$this->data->field_id}` DESC",  
  1592. 'limit' => 1 
  1593. ); 
  1594.  
  1595. if ( !empty( $params_override ) || !empty( $this->params ) ) { 
  1596. if ( !empty( $params_override ) ) 
  1597. $params = $params_override; 
  1598. elseif ( !empty( $this->params ) ) 
  1599. $params = $this->params; 
  1600.  
  1601. if ( is_object( $params ) ) { 
  1602. $params = get_object_vars( $params ); 
  1603.  
  1604. if ( 0 < $id ) { 
  1605. if ( isset( $params[ 'where' ] ) && !empty( $params[ 'where' ] ) ) { 
  1606. $params[ 'where' ] = (array) $params[ 'where' ]; 
  1607. $params[ 'where' ][] = "`t`.`{$this->data->field_id}` < {$id}"; 
  1608. else { 
  1609. $params[ 'where' ] = "`t`.`{$this->data->field_id}` < {$id}"; 
  1610. elseif ( isset( $params[ 'offset' ] ) && 0 < $params[ 'offset' ] ) 
  1611. $params[ 'offset' ] -= 1; 
  1612. elseif ( !isset( $params[ 'offset' ] ) && !empty( $this->params ) && 0 < $this->row_number ) 
  1613. $params[ 'offset' ] = $this->row_number - 1; 
  1614. else 
  1615. return 0; 
  1616.  
  1617. if ( isset( $params[ 'orderby' ] ) && !empty( $params[ 'orderby' ] ) ) { 
  1618. if ( is_array( $params[ 'orderby' ] ) ) { 
  1619. foreach ( $params[ 'orderby' ] as $orderby => $dir ) { 
  1620. $dir = strtoupper( $dir ); 
  1621.  
  1622. if ( !in_array( $dir, array( 'ASC', 'DESC' ) ) ) { 
  1623. continue; 
  1624.  
  1625. if ( 'ASC' == $dir ) { 
  1626. $params[ 'orderby' ][ $orderby ] = 'DESC'; 
  1627. else { 
  1628. $params[ 'orderby' ][ $orderby ] = 'ASC'; 
  1629.  
  1630. $params[ 'orderby' ][ $this->data->field_id ] = 'DESC'; 
  1631. elseif ( "`t`.`{$this->data->field_id}` DESC" != $params[ 'orderby' ] ) { 
  1632. $params[ 'orderby' ] .= ", `t`.`{$this->data->field_id}` DESC"; 
  1633.  
  1634. $params[ 'select' ] = "`t`.`{$this->data->field_id}`"; 
  1635. $params[ 'limit' ] = 1; 
  1636.  
  1637. $pod = pods( $this->pod, $params ); 
  1638.  
  1639. $new_id = 0; 
  1640.  
  1641. if ( $pod->fetch() ) 
  1642. $new_id = $pod->id(); 
  1643.  
  1644. $new_id = $this->do_hook( 'prev_id', $new_id, $id, $pod, $params_override ); 
  1645.  
  1646. return $new_id; 
  1647.  
  1648. /** 
  1649. * Return the next item ID, loops at the first id to return the last 
  1650. * @param int $id 
  1651. * @param array $find_params 
  1652. * @return int 
  1653. * @since 2.0 
  1654. */ 
  1655. public function next_id ( $id = null, $params_override = null ) { 
  1656. if ( null === $id ) 
  1657. $id = $this->id(); 
  1658.  
  1659. $id = (int) $id; 
  1660.  
  1661. $params = array( 
  1662. 'select' => "`t`.`{$this->data->field_id}`",  
  1663. 'where' => "{$id} < `t`.`{$this->data->field_id}`",  
  1664. 'orderby' => "`t`.`{$this->data->field_id}` ASC",  
  1665. 'limit' => 1 
  1666. ); 
  1667.  
  1668. if ( !empty( $params_override ) || !empty( $this->params ) ) { 
  1669. if ( !empty( $params_override ) ) 
  1670. $params = $params_override; 
  1671. elseif ( !empty( $this->params ) ) 
  1672. $params = $this->params; 
  1673.  
  1674. if ( is_object( $params ) ) { 
  1675. $params = get_object_vars( $params ); 
  1676.  
  1677. if ( 0 < $id ) { 
  1678. if ( isset( $params[ 'where' ] ) && !empty( $params[ 'where' ] ) ) { 
  1679. $params[ 'where' ] = (array) $params[ 'where' ]; 
  1680. $params[ 'where' ][] = "{$id} < `t`.`{$this->data->field_id}`"; 
  1681. else { 
  1682. $params[ 'where' ] = "{$id} < `t`.`{$this->data->field_id}`"; 
  1683. elseif ( !isset( $params[ 'offset' ] ) ) { 
  1684. if ( !empty( $this->params ) && -1 < $this->row_number ) 
  1685. $params[ 'offset' ] = $this->row_number + 1; 
  1686. else 
  1687. $params[ 'offset' ] = 1; 
  1688. else 
  1689. $params[ 'offset' ] += 1; 
  1690.  
  1691. $params[ 'select' ] = "`t`.`{$this->data->field_id}`"; 
  1692. $params[ 'limit' ] = 1; 
  1693.  
  1694. $pod = pods( $this->pod, $params ); 
  1695.  
  1696. $new_id = 0; 
  1697.  
  1698. if ( $pod->fetch() ) 
  1699. $new_id = $pod->id(); 
  1700.  
  1701. $new_id = $this->do_hook( 'next_id', $new_id, $id, $pod, $params_override ); 
  1702.  
  1703. return $new_id; 
  1704.  
  1705. /** 
  1706. * Return the first item ID 
  1707. * @param array $params_override 
  1708. * @return int 
  1709. * @since 2.3 
  1710. */ 
  1711. public function first_id ( $params_override = null ) { 
  1712. $params = array( 
  1713. 'select' => "`t`.`{$this->data->field_id}`",  
  1714. 'orderby' => "`t`.`{$this->data->field_id}` ASC",  
  1715. 'limit' => 1 
  1716. ); 
  1717.  
  1718. if ( !empty( $params_override ) || !empty( $this->params ) ) { 
  1719. if ( !empty( $params_override ) ) 
  1720. $params = $params_override; 
  1721. elseif ( !empty( $this->params ) ) 
  1722. $params = $this->params; 
  1723.  
  1724. if ( is_object( $params ) ) { 
  1725. $params = get_object_vars( $params ); 
  1726.  
  1727. $params[ 'select' ] = "`t`.`{$this->data->field_id}`"; 
  1728. $params[ 'offset' ] = 0; 
  1729. $params[ 'limit' ] = 1; 
  1730.  
  1731. $pod = pods( $this->pod, $params ); 
  1732.  
  1733. $new_id = 0; 
  1734.  
  1735. if ( $pod->fetch() ) 
  1736. $new_id = $pod->id(); 
  1737.  
  1738. $new_id = $this->do_hook( 'first_id', $new_id, $pod, $params_override ); 
  1739.  
  1740. return $new_id; 
  1741.  
  1742. /** 
  1743. * Return the last item ID 
  1744. * @param array $params_override 
  1745. * @return int 
  1746. * @since 2.3 
  1747. */ 
  1748. public function last_id ( $params_override = null ) { 
  1749. $params = array( 
  1750. 'select' => "`t`.`{$this->data->field_id}`",  
  1751. 'orderby' => "`t`.`{$this->data->field_id}` DESC",  
  1752. 'limit' => 1 
  1753. ); 
  1754.  
  1755. if ( !empty( $params_override ) || !empty( $this->params ) ) { 
  1756. if ( !empty( $params_override ) ) 
  1757. $params = $params_override; 
  1758. elseif ( !empty( $this->params ) ) 
  1759. $params = $this->params; 
  1760.  
  1761. if ( is_object( $params ) ) { 
  1762. $params = get_object_vars( $params ); 
  1763.  
  1764. if ( isset( $params[ 'total_found' ] ) ) 
  1765. $params[ 'offset' ] = $params[ 'total_found' ] - 1; 
  1766. else 
  1767. $params[ 'offset' ] = $this->total_found() - 1; 
  1768.  
  1769. if ( isset( $params[ 'orderby' ] ) && !empty( $params[ 'orderby' ] ) ) { 
  1770. if ( is_array( $params[ 'orderby' ] ) ) { 
  1771. foreach ( $params[ 'orderby' ] as $orderby => $dir ) { 
  1772. $dir = strtoupper( $dir ); 
  1773.  
  1774. if ( !in_array( $dir, array( 'ASC', 'DESC' ) ) ) { 
  1775. continue; 
  1776.  
  1777. if ( 'ASC' == $dir ) { 
  1778. $params[ 'orderby' ][ $orderby ] = 'DESC'; 
  1779. else { 
  1780. $params[ 'orderby' ][ $orderby ] = 'ASC'; 
  1781.  
  1782. $params[ 'orderby' ][ $this->data->field_id ] = 'DESC'; 
  1783. elseif ( "`t`.`{$this->data->field_id}` DESC" != $params[ 'orderby' ] ) { 
  1784. $params[ 'orderby' ] .= ", `t`.`{$this->data->field_id}` DESC"; 
  1785.  
  1786. $params[ 'select' ] = "`t`.`{$this->data->field_id}`"; 
  1787. $params[ 'limit' ] = 1; 
  1788.  
  1789. $pod = pods( $this->pod, $params ); 
  1790.  
  1791. $new_id = 0; 
  1792.  
  1793. if ( $pod->fetch() ) 
  1794. $new_id = $pod->id(); 
  1795.  
  1796. $new_id = $this->do_hook( 'last_id', $new_id, $pod, $params_override ); 
  1797. return $new_id; 
  1798.  
  1799. /** 
  1800. * Return the item name 
  1801. * @return string 
  1802. * @since 2.0 
  1803. */ 
  1804. public function index () { 
  1805. return $this->field( $this->data->field_index ); 
  1806.  
  1807. /** 
  1808. * Find items of a pod, much like WP_Query, but with advanced table handling. 
  1809. * @param array $params An associative array of parameters 
  1810. * @param int $limit (optional) (deprecated) Limit the number of items to find, use -1 to return all items with no limit 
  1811. * @param string $where (optional) (deprecated) SQL WHERE declaration to use 
  1812. * @param string $sql (optional) (deprecated) For advanced use, a custom SQL query to run 
  1813. * @return \Pods The pod object 
  1814. * @since 2.0 
  1815. * @link http://pods.io/docs/find/ 
  1816. */ 
  1817. public function find ( $params = null, $limit = 15, $where = null, $sql = null ) { 
  1818.  
  1819. $tableless_field_types = PodsForm::tableless_field_types(); 
  1820. $simple_tableless_objects = PodsForm::simple_tableless_objects(); 
  1821.  
  1822.  
  1823. $this->params = $params; 
  1824.  
  1825. $select = '`t`.*'; 
  1826.  
  1827. if ( !in_array( $this->pod_data[ 'type' ], array( 'pod', 'table' ) ) && 'table' == $this->pod_data[ 'storage' ] ) 
  1828. $select .= ', `d`.*'; 
  1829.  
  1830. if ( empty( $this->data->table ) ) 
  1831. return $this; 
  1832.  
  1833. $defaults = array( 
  1834. 'table' => $this->data->table,  
  1835. 'select' => $select,  
  1836. 'join' => null,  
  1837.  
  1838. 'where' => $where,  
  1839. 'groupby' => null,  
  1840. 'having' => null,  
  1841. 'orderby' => null,  
  1842.  
  1843. 'limit' => (int) $limit,  
  1844. 'offset' => null,  
  1845. 'page' => (int) $this->page,  
  1846. 'page_var' => $this->page_var,  
  1847. 'pagination' => (boolean) $this->pagination,  
  1848.  
  1849. 'search' => (boolean) $this->search,  
  1850. 'search_var' => $this->search_var,  
  1851. 'search_query' => null,  
  1852. 'search_mode' => $this->search_mode,  
  1853. 'search_across' => false,  
  1854. 'search_across_picks' => false,  
  1855. 'search_across_files' => false,  
  1856.  
  1857. 'filters' => $this->filters,  
  1858. 'sql' => $sql,  
  1859.  
  1860. 'expires' => null,  
  1861. 'cache_mode' => 'cache' 
  1862. ); 
  1863.  
  1864. if ( is_array( $params ) ) 
  1865. $params = (object) array_merge( $defaults, $params ); 
  1866. if ( is_object( $params ) ) 
  1867. $params = (object) array_merge( $defaults, get_object_vars( $params ) ); 
  1868. else { 
  1869. $defaults[ 'orderby' ] = $params; 
  1870. $params = (object) $defaults; 
  1871.  
  1872. $params = apply_filters( 'pods_pods_find', $params ); 
  1873.  
  1874. $params->limit = (int) $params->limit; 
  1875.  
  1876. if ( 0 == $params->limit ) 
  1877. $params->limit = -1; 
  1878.  
  1879. $this->limit = (int) $params->limit; 
  1880. $this->offset = (int) $params->offset; 
  1881. $this->page = (int) $params->page; 
  1882. $this->page_var = $params->page_var; 
  1883. $this->pagination = (boolean) $params->pagination; 
  1884. $this->search = (boolean) $params->search; 
  1885. $this->search_var = $params->search_var; 
  1886. $params->join = (array) $params->join; 
  1887.  
  1888. if ( empty( $params->search_query ) ) 
  1889. $params->search_query = pods_var( $this->search_var, 'get', '' ); 
  1890.  
  1891. // Allow orderby array ( 'field' => 'asc|desc' ) 
  1892. if ( !empty( $params->orderby ) && is_array( $params->orderby ) ) { 
  1893. foreach ( $params->orderby as $k => &$orderby ) { 
  1894. if ( !is_numeric( $k ) ) { 
  1895. $key = ''; 
  1896.  
  1897. $order = 'ASC'; 
  1898.  
  1899. if ( 'DESC' == strtoupper( $orderby ) ) 
  1900. $order = 'DESC'; 
  1901.  
  1902. if ( isset( $this->fields[ $k ] ) && in_array( $this->fields[ $k ][ 'type' ], $tableless_field_types ) ) { 
  1903. if ( in_array( $this->fields[ $k ][ 'pick_object' ], $simple_tableless_objects ) ) { 
  1904. if ( 'table' == $this->pod_data[ 'storage' ] ) { 
  1905. if ( !in_array( $this->pod_data[ 'type' ], array( 'pod', 'table' ) ) ) 
  1906. $key = "`d`.`{$k}`"; 
  1907. else 
  1908. $key = "`t`.`{$k}`"; 
  1909. else 
  1910. $key = "`{$k}`.`meta_value`"; 
  1911. else { 
  1912. $pick_val = $this->fields[ $k ][ 'pick_val' ]; 
  1913.  
  1914. if ( '__current__' == $pick_val ) 
  1915. $pick_val = $this->pod; 
  1916.  
  1917. $table = $this->api->get_table_info( $this->fields[ $k ][ 'pick_object' ], $pick_val ); 
  1918.  
  1919. if ( !empty( $table ) ) 
  1920. $key = "`{$k}`.`" . $table[ 'field_index' ] . '`'; 
  1921.  
  1922. if ( empty( $key ) ) { 
  1923. if ( !in_array( $this->pod_data[ 'type' ], array( 'pod', 'table' ) ) ) { 
  1924. if ( isset( $this->pod_data[ 'object_fields' ][ $k ] ) ) 
  1925. $key = "`t`.`{$k}`"; 
  1926. elseif ( isset( $this->fields[ $k ] ) ) { 
  1927. if ( 'table' == $this->pod_data[ 'storage' ] ) 
  1928. $key = "`d`.`{$k}`"; 
  1929. else 
  1930. $key = "`{$k}`.`meta_value`"; 
  1931. else { 
  1932. foreach ( $this->pod_data[ 'object_fields' ] as $object_field => $object_field_opt ) { 
  1933. if ( $object_field == $k || in_array( $k, $object_field_opt[ 'alias' ] ) ) 
  1934. $key = "`t`.`{$object_field}`"; 
  1935. elseif ( isset( $this->fields[ $k ] ) ) { 
  1936. if ( 'table' == $this->pod_data[ 'storage' ] ) 
  1937. $key = "`t`.`{$k}`"; 
  1938. else 
  1939. $key = "`{$k}`.`meta_value`"; 
  1940.  
  1941. if ( empty( $key ) ) { 
  1942. $key = $k; 
  1943.  
  1944. if ( false === strpos( $key, ' ' ) && false === strpos( $key, '`' ) ) 
  1945. $key = '`' . str_replace( '.', '`.`', $key ) . '`'; 
  1946.  
  1947. $orderby = $key; 
  1948.  
  1949. if ( false === strpos( $orderby, ' ' ) ) 
  1950. $orderby .= ' ' . $order; 
  1951.  
  1952. // Add prefix to $params->orderby if needed 
  1953. if ( !empty( $params->orderby ) ) { 
  1954. if ( !is_array( $params->orderby ) ) 
  1955. $params->orderby = array( $params->orderby ); 
  1956.  
  1957. foreach ( $params->orderby as &$prefix_orderby ) { 
  1958. if ( false === strpos( $prefix_orderby, ', ' ) && false === strpos( $prefix_orderby, '(' ) && false === stripos( $prefix_orderby, ' AS ' ) && false === strpos( $prefix_orderby, '`' ) && false === strpos( $prefix_orderby, '.' ) ) { 
  1959. if ( false !== stripos( $prefix_orderby, ' DESC' ) ) { 
  1960. $k = trim( str_ireplace( array( '`', ' DESC' ), '', $prefix_orderby ) ); 
  1961. $dir = 'DESC'; 
  1962. else { 
  1963. $k = trim( str_ireplace( array( '`', ' ASC' ), '', $prefix_orderby ) ); 
  1964. $dir = 'ASC'; 
  1965.  
  1966. $key = $k; 
  1967.  
  1968. if ( !in_array( $this->pod_data[ 'type' ], array( 'pod', 'table' ) ) ) { 
  1969. if ( isset( $this->pod_data[ 'object_fields' ][ $k ] ) ) 
  1970. $key = "`t`.`{$k}`"; 
  1971. elseif ( isset( $this->fields[ $k ] ) ) { 
  1972. if ( 'table' == $this->pod_data[ 'storage' ] ) 
  1973. $key = "`d`.`{$k}`"; 
  1974. else 
  1975. $key = "`{$k}`.`meta_value`"; 
  1976. else { 
  1977. foreach ( $this->pod_data[ 'object_fields' ] as $object_field => $object_field_opt ) { 
  1978. if ( $object_field == $k || in_array( $k, $object_field_opt[ 'alias' ] ) ) 
  1979. $key = "`t`.`{$object_field}`"; 
  1980. elseif ( isset( $this->fields[ $k ] ) ) { 
  1981. if ( 'table' == $this->pod_data[ 'storage' ] ) 
  1982. $key = "`t`.`{$k}`"; 
  1983. else 
  1984. $key = "`{$k}`.`meta_value`"; 
  1985.  
  1986. $prefix_orderby = "{$key} {$dir}"; 
  1987.  
  1988. $this->data->select( $params ); 
  1989.  
  1990. return $this; 
  1991.  
  1992. /** 
  1993. * Fetch an item from a Pod. If $id is null, it will return the next item in the list after running find(). 
  1994. * You can rewind the list back to the start by using reset(). 
  1995. * Providing an $id will fetch a specific item from a Pod, much like a call to pods(), and can handle either an id or slug. 
  1996. * @see PodsData::fetch 
  1997. * @param int $id ID or slug of the item to fetch 
  1998. * @param bool $explicit_set Whether to set explicitly (use false when in loop) 
  1999. * @return array An array of fields from the row 
  2000. * @since 2.0 
  2001. * @link http://pods.io/docs/fetch/ 
  2002. */ 
  2003. public function fetch ( $id = null, $explicit_set = true ) { 
  2004. /** 
  2005. * Runs directly before an item is fetched by fetch() 
  2006. * @since unknown 
  2007. * @param int|string|null $id Item ID being fetched or null. 
  2008. * @param object|Pods $this Current Pods object. 
  2009. */ 
  2010. do_action( 'pods_pods_fetch', $id, $this ); 
  2011.  
  2012. if ( !empty( $id ) ) 
  2013. $this->params = array(); 
  2014.  
  2015. $this->data->fetch( $id, $explicit_set ); 
  2016.  
  2017. return $this->row; 
  2018.  
  2019. /** 
  2020. * (Re)set the MySQL result pointer 
  2021. * @see PodsData::reset 
  2022. * @param int $row ID of the row to reset to 
  2023. * @return \Pods The pod object 
  2024. * @since 2.0 
  2025. * @link http://pods.io/docs/reset/ 
  2026. */ 
  2027. public function reset ( $row = null ) { 
  2028. /** 
  2029. * Runs directly before the Pods object is reset by reset() 
  2030. * @since unknown 
  2031. * @param int|string|null The ID of the row being reset to or null if being reset to the beginningg. 
  2032. * @param object|Pods $this Current Pods object. 
  2033. */ 
  2034. do_action( 'pods_pods_reset', $row, $this ); 
  2035.  
  2036. $this->data->reset( $row ); 
  2037.  
  2038. return $this; 
  2039.  
  2040. /** 
  2041. * Fetch the total row count returned by the last call to find(), based on the 'limit' parameter set. 
  2042. * This is different than the total number of rows found in the database, which you can get with total_found(). 
  2043. * @see PodsData::total 
  2044. * @return int Number of rows returned by find(), based on the 'limit' parameter set 
  2045. * @since 2.0 
  2046. * @link http://pods.io/docs/total/ 
  2047. */ 
  2048. public function total () { 
  2049. do_action( 'pods_pods_total', $this ); 
  2050.  
  2051. $this->data->total(); 
  2052.  
  2053. $this->total =& $this->data->total; 
  2054.  
  2055. return $this->total; 
  2056.  
  2057. /** 
  2058. * Fetch the total amount of rows found by the last call to find(), regardless of the 'limit' parameter set. 
  2059. * This is different than the total number of rows limited by the current call, which you can get with total(). 
  2060. * @see PodsData::total_found 
  2061. * @return int Number of rows returned by find(), regardless of the 'limit' parameter 
  2062. * @since 2.0 
  2063. * @link http://pods.io/docs/total-found/ 
  2064. */ 
  2065. public function total_found () { 
  2066. /** 
  2067. * Runs directly before the value of total_found() is determined and returned. 
  2068. * @since unknown 
  2069. * @param object|Pods $this Current Pods object. 
  2070. */ 
  2071. do_action( 'pods_pods_total_found', $this ); 
  2072.  
  2073. $this->data->total_found(); 
  2074.  
  2075. $this->total_found =& $this->data->total_found; 
  2076.  
  2077. return $this->total_found; 
  2078.  
  2079. /** 
  2080. * Fetch the total number of pages, based on total rows found and the last find() limit 
  2081. * @param null|int $limit Rows per page 
  2082. * @param null|int $offset Offset of rows 
  2083. * @param null|int $total Total rows 
  2084. * @return int Number of pages 
  2085. * @since 2.3.10 
  2086. */ 
  2087. public function total_pages( $limit = null, $offset = null, $total = null ) { 
  2088.  
  2089. $this->do_hook( 'total_pages' ); 
  2090.  
  2091. if ( null === $limit ) { 
  2092. $limit = $this->limit; 
  2093.  
  2094. if ( null === $offset ) { 
  2095. $offset = $this->offset; 
  2096.  
  2097. if ( null === $total ) { 
  2098. $total = $this->total_found(); 
  2099.  
  2100. $total_pages = ceil( ( $total - $offset ) / $limit ); 
  2101.  
  2102. return $total_pages; 
  2103.  
  2104.  
  2105. /** 
  2106. * Fetch the zebra switch 
  2107. * @see PodsData::zebra 
  2108. * @return bool Zebra state 
  2109. * @since 1.12 
  2110. */ 
  2111. public function zebra () { 
  2112. $this->do_hook( 'zebra' ); 
  2113.  
  2114. return $this->data->zebra(); 
  2115.  
  2116. /** 
  2117. * Fetch the nth state 
  2118. * @see PodsData::nth 
  2119. * @param int|string $nth The $nth to match on the PodsData::row_number 
  2120. * @return bool Whether $nth matches 
  2121. * @since 2.3 
  2122. */ 
  2123. public function nth ( $nth = null ) { 
  2124. $this->do_hook( 'nth', $nth ); 
  2125.  
  2126. return $this->data->nth( $nth ); 
  2127.  
  2128. /** 
  2129. * Fetch the current position in the loop (starting at 1) 
  2130. * @see PodsData::position 
  2131. * @return int Current row number (+1) 
  2132. * @since 2.3 
  2133. */ 
  2134. public function position () { 
  2135. $this->do_hook( 'position' ); 
  2136.  
  2137. return $this->data->position(); 
  2138.  
  2139. /** 
  2140. * Add an item to a Pod by giving an array of field data or set a specific field to 
  2141. * a specific value if you're just wanting to add a new item but only set one field. 
  2142. * You may be looking for save() in most cases where you're setting a specific field. 
  2143. * @see PodsAPI::save_pod_item 
  2144. * @param array|string $data Either an associative array of field information or a field name 
  2145. * @param mixed $value (optional) Value of the field, if $data is a field name 
  2146. * @return int The item ID 
  2147. * @since 2.0 
  2148. * @link http://pods.io/docs/add/ 
  2149. */ 
  2150. public function add ( $data = null, $value = null ) { 
  2151. if ( null !== $value ) 
  2152. $data = array( $data => $value ); 
  2153.  
  2154. $data = (array) $this->do_hook( 'add', $data ); 
  2155.  
  2156. if ( empty( $data ) ) 
  2157. return 0; 
  2158.  
  2159. $params = array( 
  2160. 'pod' => $this->pod,  
  2161. 'data' => $data,  
  2162. 'allow_custom_fields' => true 
  2163. ); 
  2164.  
  2165. return $this->api->save_pod_item( $params ); 
  2166.  
  2167. /** 
  2168. * Add an item to the values of a relationship field, add a value to a number field (field+1), add time to a date field, or add text to a text field 
  2169. * @see PodsAPI::save_pod_item 
  2170. * @param string $field Field name 
  2171. * @param mixed $value ID(s) to add, int|float to add to number field, string for dates (+1 week), or string for text 
  2172. * @param int $id (optional) ID of the pod item to update 
  2173. * @return int The item ID 
  2174. * @since 2.3 
  2175. */ 
  2176. public function add_to ( $field, $value, $id = null ) { 
  2177. $pod =& $this; 
  2178.  
  2179. $fetch = false; 
  2180.  
  2181. if ( null === $id ) { 
  2182. $fetch = true; 
  2183.  
  2184. $id = $this->id(); 
  2185. elseif ( $id != $this->id() ) 
  2186. $pod = pods( $this->pod, $id ); 
  2187.  
  2188. $this->do_hook( 'add_to', $field, $value, $id ); 
  2189.  
  2190. if ( !isset( $this->fields[ $field ] ) ) 
  2191. return $id; 
  2192.  
  2193. // Tableless fields 
  2194. if ( in_array( $this->fields[ $field ][ 'type' ], PodsForm::tableless_field_types() ) ) { 
  2195. if ( !is_array( $value ) ) 
  2196. $value = explode( ', ', $value ); 
  2197.  
  2198. if ( 'pick' == $this->fields[ $field ][ 'type' ] && in_array( $this->fields[ $field ][ 'pick_object' ], PodsForm::simple_tableless_objects() ) ) { 
  2199. $current_value = $pod->raw( $field ); 
  2200.  
  2201. if ( !empty( $current_value ) || ( !is_array( $current_value ) && 0 < strlen( $current_value ) ) ) 
  2202. $current_value = (array) $current_value; 
  2203. else 
  2204. $current_value = array(); 
  2205.  
  2206. $value = array_merge( $current_value, $value ); 
  2207. else { 
  2208. $related_ids = $this->api->lookup_related_items( $this->fields[ $field ][ 'id' ], $this->pod_data[ 'id' ], $id, $this->fields[ $field ], $this->pod_data ); 
  2209.  
  2210. foreach ( $value as $k => $v ) { 
  2211. if ( !preg_match( '/[^0-9]/', $v ) ) 
  2212. $value[ $k ] = (int) $v; 
  2213.  
  2214. $value = array_merge( $related_ids, $value ); 
  2215.  
  2216. if ( !empty( $value ) ) 
  2217. $value = array_filter( array_unique( $value ) ); 
  2218. else 
  2219. $value = array(); 
  2220.  
  2221. if ( empty( $value ) ) 
  2222. return $id; 
  2223. // Number fields 
  2224. elseif ( in_array( $this->fields[ $field ][ 'type' ], PodsForm::number_field_types() ) ) { 
  2225. $current_value = (float) $pod->raw( $field ); 
  2226.  
  2227. $value = ( $current_value + (float) $value ); 
  2228. // Date fields 
  2229. elseif ( in_array( $this->fields[ $field ][ 'type' ], PodsForm::date_field_types() ) ) { 
  2230. $current_value = $pod->raw( $field ); 
  2231.  
  2232. if ( 0 < strlen( $current_value ) ) 
  2233. $value = strtotime( $value, strtotime( $current_value ) ); 
  2234. else 
  2235. $value = strtotime( $value ); 
  2236. // Text fields 
  2237. elseif ( in_array( $this->fields[ $field ][ 'type' ], PodsForm::text_field_types() ) ) { 
  2238. $current_value = $pod->raw( $field ); 
  2239.  
  2240. if ( 0 < strlen( $current_value ) ) 
  2241. $value = $current_value . $value; 
  2242.  
  2243. // @todo handle object fields and taxonomies 
  2244.  
  2245. $params = array( 
  2246. 'pod' => $this->pod,  
  2247. 'id' => $id,  
  2248. 'data' => array( 
  2249. $field => $value 
  2250. ); 
  2251.  
  2252. $id = $this->api->save_pod_item( $params ); 
  2253.  
  2254. if ( 0 < $id && $fetch ) 
  2255. $pod->fetch( $id, false ); 
  2256.  
  2257. return $id; 
  2258.  
  2259. /** 
  2260. * Remove an item from the values of a relationship field, remove a value from a number field (field-1), remove time to a date field 
  2261. * @see PodsAPI::save_pod_item 
  2262. * @param string $field Field name 
  2263. * @param mixed $value ID(s) to add, int|float to add to number field, string for dates (-1 week), or string for text 
  2264. * @param int $id (optional) ID of the pod item to update 
  2265. * @return int The item ID 
  2266. * @since 2.3.3 
  2267. */ 
  2268. public function remove_from( $field, $value = null, $id = null ) { 
  2269.  
  2270. $pod =& $this; 
  2271.  
  2272. $fetch = false; 
  2273.  
  2274. if ( null === $id ) { 
  2275. $fetch = true; 
  2276.  
  2277. $id = $this->id(); 
  2278. elseif ( $id != $this->id() ) { 
  2279. $pod = pods( $this->pod, $id ); 
  2280.  
  2281. $this->do_hook( 'remove_from', $field, $value, $id ); 
  2282.  
  2283. if ( !isset( $this->fields[ $field ] ) ) { 
  2284. return $id; 
  2285.  
  2286. // Tableless fields 
  2287. if ( in_array( $this->fields[ $field ][ 'type' ], PodsForm::tableless_field_types() ) ) { 
  2288. if ( empty( $value ) ) { 
  2289. $value = array(); 
  2290.  
  2291. if ( !empty( $value ) ) { 
  2292. if ( !is_array( $value ) ) { 
  2293. $value = explode( ', ', $value ); 
  2294.  
  2295. if ( 'pick' == $this->fields[ $field ][ 'type' ] && in_array( $this->fields[ $field ][ 'pick_object' ], PodsForm::simple_tableless_objects() ) ) { 
  2296. $current_value = $pod->raw( $field ); 
  2297.  
  2298. if ( !empty( $current_value ) ) { 
  2299. $current_value = (array) $current_value; 
  2300.  
  2301. foreach ( $current_value as $k => $v ) { 
  2302. if ( in_array( $v, $value ) ) { 
  2303. unset( $current_value[ $k ] ); 
  2304.  
  2305. $value = $current_value; 
  2306. else { 
  2307. $related_ids = $this->api->lookup_related_items( $this->fields[ $field ][ 'id' ], $this->pod_data[ 'id' ], $id, $this->fields[ $field ], $this->pod_data ); 
  2308.  
  2309. foreach ( $value as $k => $v ) { 
  2310. if ( !preg_match( '/[^0-9]/', $v ) ) { 
  2311. $value[ $k ] = (int) $v; 
  2312. // @todo Convert slugs into IDs 
  2313. else { 
  2314.  
  2315.  
  2316. foreach ( $related_ids as $k => $v ) { 
  2317. if ( in_array( $v, $value ) ) { 
  2318. unset( $related_ids[ $k ] ); 
  2319.  
  2320. $value = $related_ids; 
  2321.  
  2322. if ( !empty( $value ) ) { 
  2323. $value = array_filter( array_unique( $value ) ); 
  2324. else { 
  2325. $value = array(); 
  2326. // Number fields 
  2327. elseif ( in_array( $this->fields[ $field ][ 'type' ], PodsForm::number_field_types() ) ) { 
  2328. // Date fields don't support empty for removing 
  2329. if ( empty( $value ) ) { 
  2330. return $id; 
  2331.  
  2332. $current_value = (float) $pod->raw( $field ); 
  2333.  
  2334. $value = ( $current_value - (float) $value ); 
  2335. // Date fields 
  2336. elseif ( in_array( $this->fields[ $field ][ 'type' ], PodsForm::date_field_types() ) ) { 
  2337. // Date fields don't support empty for removing 
  2338. if ( empty( $value ) ) { 
  2339. return $id; 
  2340.  
  2341. $current_value = $pod->raw( $field ); 
  2342.  
  2343. if ( 0 < strlen( $current_value ) ) { 
  2344. $value = strtotime( $value, strtotime( $current_value ) ); 
  2345. else { 
  2346. $value = strtotime( $value ); 
  2347.  
  2348. $value = date_i18n( 'Y-m-d h:i:s', $value ); 
  2349.  
  2350. // @todo handle object fields and taxonomies 
  2351.  
  2352. $params = array( 
  2353. 'pod' => $this->pod,  
  2354. 'id' => $id,  
  2355. 'data' => array( 
  2356. $field => $value 
  2357. ); 
  2358.  
  2359. $id = $this->api->save_pod_item( $params ); 
  2360.  
  2361. if ( 0 < $id && $fetch ) { 
  2362. $pod->fetch( $id, false ); 
  2363.  
  2364. return $id; 
  2365.  
  2366.  
  2367. /** 
  2368. * Save an item by giving an array of field data or set a specific field to a specific value. 
  2369. * Though this function has the capacity to add new items, best practice should direct you 
  2370. * to use add() for that instead. 
  2371. * @see PodsAPI::save_pod_item 
  2372. * @param array|string $data Either an associative array of field information or a field name 
  2373. * @param mixed $value (optional) Value of the field, if $data is a field name 
  2374. * @param int $id (optional) ID of the pod item to update 
  2375. * @param array $params (optional) Additional params to send to save_pod_item 
  2376. * @return int The item ID 
  2377. * @since 2.0 
  2378. * @link http://pods.io/docs/save/ 
  2379. */ 
  2380. public function save ( $data = null, $value = null, $id = null, $params = null ) { 
  2381. if ( null !== $value ) 
  2382. $data = array( $data => $value ); 
  2383.  
  2384. $fetch = false; 
  2385.  
  2386. if ( null === $id || ( $this->row && $id == $this->id() ) ) { 
  2387. $fetch = true; 
  2388.  
  2389. if ( null === $id ) { 
  2390. $id = $this->id(); 
  2391.  
  2392. $data = (array) $this->do_hook( 'save', $data, $id ); 
  2393.  
  2394. if ( empty( $data ) ) 
  2395. return $id; 
  2396.  
  2397. $default = array(); 
  2398.  
  2399. if ( !empty( $params ) && is_array( $params ) ) 
  2400. $default = $params; 
  2401.  
  2402. $params = array( 
  2403. 'pod' => $this->pod,  
  2404. 'id' => $id,  
  2405. 'data' => $data,  
  2406. 'allow_custom_fields' => true,  
  2407. 'clear_slug_cache' => false 
  2408. ); 
  2409.  
  2410. if ( !empty( $default ) ) 
  2411. $params = array_merge( $params, $default ); 
  2412.  
  2413. $id = $this->api->save_pod_item( $params ); 
  2414.  
  2415. if ( 0 < $id && $fetch ) 
  2416. $this->fetch( $id, false ); 
  2417.  
  2418. if ( !empty( $this->pod_data[ 'field_slug' ] ) ) { 
  2419. if ( 0 < $id && $fetch ) { 
  2420. $slug = $this->field( $this->pod_data[ 'field_slug' ] ); 
  2421. else { 
  2422. $slug = pods( $this->pod, $id )->field( $this->pod_data[ 'field_slug' ] ); 
  2423.  
  2424. if ( 0 < strlen( $slug ) ) { 
  2425. pods_cache_clear( $slug, 'pods_items_' . $this->pod ); 
  2426.  
  2427. return $id; 
  2428.  
  2429. /** 
  2430. * Delete an item 
  2431. * @see PodsAPI::delete_pod_item 
  2432. * @param int $id ID of the Pod item to delete 
  2433. * @return bool Whether the item was successfully deleted 
  2434. * @since 2.0 
  2435. * @link http://pods.io/docs/delete/ 
  2436. */ 
  2437. public function delete ( $id = null ) { 
  2438. if ( null === $id ) 
  2439. $id = $this->id(); 
  2440.  
  2441. $id = (int) $this->do_hook( 'delete', $id ); 
  2442.  
  2443. if ( empty( $id ) ) 
  2444. return false; 
  2445.  
  2446. $params = array( 
  2447. 'pod' => $this->pod,  
  2448. 'id' => $id 
  2449. ); 
  2450.  
  2451. return $this->api->delete_pod_item( $params ); 
  2452.  
  2453. /** 
  2454. * Reset Pod 
  2455. * @see PodsAPI::reset_pod 
  2456. * @return bool Whether the Pod was successfully reset 
  2457. * @since 2.1.1 
  2458. */ 
  2459. public function reset_pod () { 
  2460. $params = array( 'id' => $this->pod_id ); 
  2461.  
  2462. $this->data->id = null; 
  2463. $this->data->row = array(); 
  2464. $this->data->data = array(); 
  2465.  
  2466. $this->data->total = 0; 
  2467. $this->data->total_found = 0; 
  2468.  
  2469. return $this->api->reset_pod( $params ); 
  2470.  
  2471. /** 
  2472. * Duplicate an item 
  2473. * @see PodsAPI::duplicate_pod_item 
  2474. * @param int $id ID of the pod item to duplicate 
  2475. * @return int|bool ID of the new pod item 
  2476. * @since 2.0 
  2477. * @link http://pods.io/docs/duplicate/ 
  2478. */ 
  2479. public function duplicate ( $id = null ) { 
  2480. if ( null === $id ) 
  2481. $id = $this->id(); 
  2482.  
  2483. $id = (int) $this->do_hook( 'duplicate', $id ); 
  2484.  
  2485. if ( empty( $id ) ) 
  2486. return false; 
  2487.  
  2488. $params = array( 
  2489. 'pod' => $this->pod,  
  2490. 'id' => $id 
  2491. ); 
  2492.  
  2493. return $this->api->duplicate_pod_item( $params ); 
  2494.  
  2495. /** 
  2496. * Import data / Save multiple rows of data at once 
  2497. * @see PodsAPI::import 
  2498. * @param mixed $import_data PHP associative array or CSV input 
  2499. * @param bool $numeric_mode Use IDs instead of the name field when matching 
  2500. * @param string $format Format of import data, options are php or csv 
  2501. * @return array IDs of imported items 
  2502. * @since 2.3 
  2503. */ 
  2504. public function import ( $import_data, $numeric_mode = false, $format = null ) { 
  2505. return $this->api->import( $import_data, $numeric_mode, $format ); 
  2506.  
  2507. /** 
  2508. * Export an item's data 
  2509. * @see PodsAPI::export_pod_item 
  2510. * @param array $fields (optional) Fields to export 
  2511. * @param int $id (optional) ID of the pod item to export 
  2512. * @return array|bool Data array of the exported pod item 
  2513. * @since 2.0 
  2514. * @link http://pods.io/docs/export/ 
  2515. */ 
  2516. public function export ( $fields = null, $id = null, $format = null ) { 
  2517. $params = array( 
  2518. 'pod' => $this->pod,  
  2519. 'id' => $id,  
  2520. 'fields' => null,  
  2521. 'depth' => 2,  
  2522. 'flatten' => false 
  2523. ); 
  2524.  
  2525. if ( is_array( $fields ) && ( isset( $fields[ 'fields' ] ) || isset( $fields[ 'depth' ] ) ) ) 
  2526. $params = array_merge( $params, $fields ); 
  2527. else 
  2528. $params[ 'fields' ] = $fields; 
  2529.  
  2530. if ( isset( $params[ 'fields' ] ) && is_array( $params[ 'fields' ] ) && !in_array( $this->pod_data[ 'field_id' ], $params[ 'fields' ] ) ) 
  2531. $params[ 'fields' ] = array_merge( array( $this->pod_data[ 'field_id' ] ), $params[ 'fields' ] ); 
  2532.  
  2533. if ( null === $params[ 'id' ] ) 
  2534. $params[ 'id' ] = $this->id(); 
  2535.  
  2536. $params = (array) $this->do_hook( 'export', $params ); 
  2537.  
  2538. if ( empty( $params[ 'id' ] ) ) 
  2539. return false; 
  2540.  
  2541. $data = $this->api->export_pod_item( $params ); 
  2542.  
  2543. if ( !empty( $format ) ) { 
  2544. if ( 'json' == $format ) 
  2545. $data = json_encode( (array) $data ); 
  2546. // @todo more formats 
  2547.  
  2548. return $data; 
  2549.  
  2550. /** 
  2551. * Export data from all items 
  2552. * @see PodsAPI::export 
  2553. * @param array $params An associative array of parameters 
  2554. * @return array Data arrays of all exported pod items 
  2555. * @since 2.3 
  2556. */ 
  2557. public function export_data ( $params = null ) { 
  2558. $defaults = array( 
  2559. 'fields' => null,  
  2560. 'depth' => 2,  
  2561. 'params' => null 
  2562. ); 
  2563.  
  2564. if ( empty( $params ) ) 
  2565. $params = $defaults; 
  2566. else 
  2567. $params = array_merge( $defaults, (array) $params ); 
  2568.  
  2569. return $this->api->export( $this, $params ); 
  2570.  
  2571. /** 
  2572. * Display the pagination controls, types supported by default 
  2573. * are simple, paginate and advanced. The base and format parameters 
  2574. * are used only for the paginate view. 
  2575. * @var array $params Associative array of parameters 
  2576. * @return string Pagination HTML 
  2577. * @since 2.0 
  2578. * @link http://pods.io/docs/pagination/ 
  2579. */ 
  2580. public function pagination( $params = null ) { 
  2581.  
  2582. if ( empty( $params ) ) { 
  2583. $params = array(); 
  2584. elseif ( !is_array( $params ) ) { 
  2585. $params = array( 'label' => $params ); 
  2586.  
  2587. $this->page_var = pods_var_raw( 'page_var', $params, $this->page_var ); 
  2588.  
  2589. $url = pods_query_arg( null, null, $this->page_var ); 
  2590.  
  2591. $append = '?'; 
  2592.  
  2593. if ( false !== strpos( $url, '?' ) ) { 
  2594. $append = '&'; 
  2595.  
  2596. $defaults = array( 
  2597. 'type' => 'advanced',  
  2598. 'label' => __( 'Go to page:', 'pods' ),  
  2599. 'show_label' => true,  
  2600. 'first_text' => __( '« First', 'pods' ),  
  2601. 'prev_text' => __( '‹ Previous', 'pods' ),  
  2602. 'next_text' => __( 'Next ›', 'pods' ),  
  2603. 'last_text' => __( 'Last »', 'pods' ),  
  2604. 'prev_next' => true,  
  2605. 'first_last' => true,  
  2606. 'limit' => (int) $this->limit,  
  2607. 'offset' => (int) $this->offset,  
  2608. 'page' => max( 1, (int) $this->page ),  
  2609. 'mid_size' => 2,  
  2610. 'end_size' => 1,  
  2611. 'total_found' => $this->total_found(),  
  2612. 'page_var' => $this->page_var,  
  2613. 'base' => "{$url}{$append}%_%",  
  2614. 'format' => "{$this->page_var}=%#%",  
  2615. 'class' => '',  
  2616. 'link_class' => '' 
  2617. ); 
  2618.  
  2619. $params = (object) array_merge( $defaults, $params ); 
  2620.  
  2621. $params->total = $this->total_pages( $params->limit, $params->offset, $params->total_found ); 
  2622.  
  2623. if ( $params->limit < 1 || $params->total_found < 1 || 1 == $params->total || $params->total_found <= $params->offset ) { 
  2624. return $this->do_hook( 'pagination', $this->do_hook( 'pagination_' . $params->type, '', $params ), $params ); 
  2625.  
  2626. $pagination = $params->type; 
  2627.  
  2628. if ( !in_array( $params->type, array( 'simple', 'advanced', 'paginate', 'list' ) ) ) { 
  2629. $pagination = 'advanced'; 
  2630.  
  2631. ob_start(); 
  2632.  
  2633. pods_view( PODS_DIR . 'ui/front/pagination/' . $pagination . '.php', compact( array_keys( get_defined_vars() ) ) ); 
  2634.  
  2635. $output = ob_get_clean(); 
  2636.  
  2637. return $this->do_hook( 'pagination', $this->do_hook( 'pagination_' . $params->type, $output, $params ), $params ); 
  2638.  
  2639.  
  2640. /** 
  2641. * Return a filter form for searching a Pod 
  2642. * @var array|string $params Comma-separated list of fields or array of parameters 
  2643. * @return string Filters HTML 
  2644. * @since 2.0 
  2645. * @link http://pods.io/docs/filters/ 
  2646. */ 
  2647. public function filters ( $params = null ) { 
  2648. $defaults = array( 
  2649. 'fields' => $params,  
  2650. 'label' => '',  
  2651. 'action' => '',  
  2652. 'search' => '' 
  2653. ); 
  2654.  
  2655. if ( is_array( $params ) ) 
  2656. $params = array_merge( $defaults, $params ); 
  2657. else 
  2658. $params = $defaults; 
  2659.  
  2660. $pod =& $this; 
  2661.  
  2662. $params = apply_filters( 'pods_filters_params', $params, $pod ); 
  2663.  
  2664. $fields = $params[ 'fields' ]; 
  2665.  
  2666. if ( null !== $fields && !is_array( $fields ) && 0 < strlen( $fields ) ) 
  2667. $fields = explode( ', ', $fields ); 
  2668.  
  2669. $object_fields = (array) pods_var_raw( 'object_fields', $this->pod_data, array(), null, true ); 
  2670.  
  2671. // Force array 
  2672. if ( empty( $fields ) ) 
  2673. $fields = array(); 
  2674. else { 
  2675. $filter_fields = $fields; // Temporary 
  2676.  
  2677. $fields = array(); 
  2678.  
  2679. foreach ( $filter_fields as $k => $field ) { 
  2680. $name = $k; 
  2681.  
  2682. $defaults = array( 
  2683. 'name' => $name 
  2684. ); 
  2685.  
  2686. if ( !is_array( $field ) ) { 
  2687. $name = $field; 
  2688.  
  2689. $field = array( 
  2690. 'name' => $name 
  2691. ); 
  2692.  
  2693. $field = array_merge( $defaults, $field ); 
  2694.  
  2695. $field[ 'name' ] = trim( $field[ 'name' ] ); 
  2696.  
  2697. if ( pods_var_raw( 'hidden', $field, false, null, true ) ) 
  2698. $field[ 'type' ] = 'hidden'; 
  2699.  
  2700. if ( isset( $object_fields[ $field[ 'name' ] ] ) ) 
  2701. $fields[ $field[ 'name' ] ] = array_merge( $object_fields[ $field[ 'name' ] ], $field ); 
  2702. elseif ( isset( $this->fields[ $field[ 'name' ] ] ) ) 
  2703. $fields[ $field[ 'name' ] ] = array_merge( $this->fields[ $field[ 'name' ] ], $field ); 
  2704.  
  2705. unset( $filter_fields ); // Cleanup 
  2706.  
  2707. $this->filters = array_keys( $fields ); 
  2708.  
  2709. $label = $params[ 'label' ]; 
  2710.  
  2711. if ( strlen( $label ) < 1 ) 
  2712. $label = __( 'Search', 'pods' ); 
  2713.  
  2714. $action = $params[ 'action' ]; 
  2715.  
  2716. $search = trim( $params[ 'search' ] ); 
  2717.  
  2718. if ( strlen( $search ) < 1 ) 
  2719. $search = pods_var_raw( $pod->search_var, 'get', '' ); 
  2720.  
  2721. ob_start(); 
  2722.  
  2723. pods_view( PODS_DIR . 'ui/front/filters.php', compact( array_keys( get_defined_vars() ) ) ); 
  2724.  
  2725. $output = ob_get_clean(); 
  2726.  
  2727. /** 
  2728. * Filter the HTML output of filters() 
  2729. * @since unknown 
  2730. * @param string $output 
  2731. * @param array $params Params array passed to filters(). 
  2732. * @param object|Pods $this Current Pods object. 
  2733. */ 
  2734. return apply_filters( 'pods_pods_filters', $output, $params, $this ); 
  2735.  
  2736. /** 
  2737. * Run a helper within a Pod Page or WP Template 
  2738. * @see Pods_Helpers::helper 
  2739. * @param string $helper Helper name 
  2740. * @param string $value Value to run the helper on 
  2741. * @param string $name Field name 
  2742. * @return mixed Anything returned by the helper 
  2743. * @since 2.0 
  2744. */ 
  2745. public function helper ( $helper, $value = null, $name = null ) { 
  2746. $params = array( 
  2747. 'helper' => $helper,  
  2748. 'value' => $value,  
  2749. 'name' => $name,  
  2750. 'deprecated' => false 
  2751. ); 
  2752.  
  2753. if ( class_exists( 'Pods_Templates' ) ) 
  2754. $params[ 'deprecated' ] = Pods_Templates::$deprecated; 
  2755.  
  2756. if ( is_array( $helper ) ) 
  2757. $params = array_merge( $params, $helper ); 
  2758.  
  2759. if ( class_exists( 'Pods_Helpers' ) ) 
  2760. $value = Pods_Helpers::helper( $params, $this ); 
  2761. elseif ( function_exists( $params[ 'helper' ] ) ) 
  2762. $value = call_user_func( $params[ 'helper' ], $value ); 
  2763. else 
  2764. $value = apply_filters( $params[ 'helper' ], $value ); 
  2765.  
  2766. return $value; 
  2767.  
  2768. /** 
  2769. * Display the page template 
  2770. * @see Pods_Templates::template 
  2771. * @param string $template The template name 
  2772. * @param string $code Custom template code to use instead 
  2773. * @param bool $deprecated Whether to use deprecated functionality based on old function usage 
  2774. * @return mixed Template output 
  2775. * @since 2.0 
  2776. * @link http://pods.io/docs/template/ 
  2777. */ 
  2778. public function template ( $template_name, $code = null, $deprecated = false ) { 
  2779. $out = null; 
  2780.  
  2781. $obj =& $this; 
  2782.  
  2783. if ( !empty( $code ) ) { 
  2784. $code = str_replace( '$this->', '$obj->', $code ); // backwards compatibility 
  2785.  
  2786. $code = apply_filters( 'pods_templates_pre_template', $code, $template_name, $this ); 
  2787. $code = apply_filters( "pods_templates_pre_template_{$template_name}", $code, $template_name, $this ); 
  2788.  
  2789. ob_start(); 
  2790.  
  2791. if ( !empty( $code ) ) { 
  2792. // Only detail templates need $this->id 
  2793. if ( empty( $this->id ) ) { 
  2794. while ( $this->fetch() ) { 
  2795. echo $this->do_magic_tags( $code ); 
  2796. else 
  2797. echo $this->do_magic_tags( $code ); 
  2798.  
  2799. $out = ob_get_clean(); 
  2800.  
  2801. $out = apply_filters( 'pods_templates_post_template', $out, $code, $template_name, $this ); 
  2802. $out = apply_filters( "pods_templates_post_template_{$template_name}", $out, $code, $template_name, $this ); 
  2803. elseif ( class_exists( 'Pods_Templates' ) ) 
  2804. $out = Pods_Templates::template( $template_name, $code, $this, $deprecated ); 
  2805. elseif ( $template_name == trim( preg_replace( '/[^a-zA-Z0-9_\-\/]/', '', $template_name ), ' /-' ) ) { 
  2806. ob_start(); 
  2807.  
  2808. $default_templates = array( 
  2809. 'pods/' . $template_name,  
  2810. 'pods-' . $template_name,  
  2811. $template_name 
  2812. ); 
  2813.  
  2814. $default_templates = apply_filters( 'pods_template_default_templates', $default_templates ); 
  2815.  
  2816. // Only detail templates need $this->id 
  2817. if ( empty( $this->id ) ) { 
  2818. while ( $this->fetch() ) { 
  2819. pods_template_part( $default_templates, compact( array_keys( get_defined_vars() ) ) ); 
  2820. else 
  2821. pods_template_part( $default_templates, compact( array_keys( get_defined_vars() ) ) ); 
  2822.  
  2823. $out = ob_get_clean(); 
  2824.  
  2825. $out = apply_filters( 'pods_templates_post_template', $out, $code, $template_name, $this ); 
  2826. $out = apply_filters( "pods_templates_post_template_{$template_name}", $out, $code, $template_name, $this ); 
  2827.  
  2828. return $out; 
  2829.  
  2830. /** 
  2831. * Embed a form to add / edit a pod item from within your theme. Provide an array of $fields to include 
  2832. * and override options where needed. For WP object based Pods, you can pass through the WP object 
  2833. * field names too, such as "post_title" or "post_content" for example. 
  2834. * @param array $params (optional) Fields to show on the form, defaults to all fields 
  2835. * @param string $label (optional) Save button label, defaults to "Save Changes" 
  2836. * @param string $thank_you (optional) Thank you URL to send to upon success 
  2837. * @return bool|mixed 
  2838. * @since 2.0 
  2839. * @link http://pods.io/docs/form/ 
  2840. */ 
  2841. public function form ( $params = null, $label = null, $thank_you = null ) { 
  2842. $defaults = array( 
  2843. 'fields' => $params,  
  2844. 'label' => $label,  
  2845. 'thank_you' => $thank_you,  
  2846. 'fields_only' => false 
  2847. ); 
  2848.  
  2849. if ( is_array( $params ) ) 
  2850. $params = array_merge( $defaults, $params ); 
  2851. else 
  2852. $params = $defaults; 
  2853.  
  2854. $pod =& $this; 
  2855.  
  2856. $params = $this->do_hook( 'form_params', $params ); 
  2857.  
  2858. $fields = $params[ 'fields' ]; 
  2859.  
  2860. if ( null !== $fields && !is_array( $fields ) && 0 < strlen( $fields ) ) 
  2861. $fields = explode( ', ', $fields ); 
  2862.  
  2863. $object_fields = (array) pods_var_raw( 'object_fields', $this->pod_data, array(), null, true ); 
  2864.  
  2865. if ( empty( $fields ) ) { 
  2866. // Add core object fields if $fields is empty 
  2867. $fields = array_merge( $object_fields, $this->fields ); 
  2868.  
  2869. $form_fields = $fields; // Temporary 
  2870.  
  2871. $fields = array(); 
  2872.  
  2873. foreach ( $form_fields as $k => $field ) { 
  2874. $name = $k; 
  2875.  
  2876. $defaults = array( 
  2877. 'name' => $name 
  2878. ); 
  2879.  
  2880. if ( !is_array( $field ) ) { 
  2881. $name = $field; 
  2882.  
  2883. $field = array( 
  2884. 'name' => $name 
  2885. ); 
  2886.  
  2887. $field = array_merge( $defaults, $field ); 
  2888.  
  2889. $field[ 'name' ] = trim( $field[ 'name' ] ); 
  2890.  
  2891. $default_value = pods_var_raw( 'default', $field ); 
  2892. $value = pods_var_raw( 'value', $field ); 
  2893.  
  2894. if ( empty( $field[ 'name' ] ) ) 
  2895. $field[ 'name' ] = trim( $name ); 
  2896.  
  2897. if ( isset( $object_fields[ $field[ 'name' ] ] ) ) { 
  2898. $field = array_merge( $object_fields[ $field[ 'name' ] ], $field ); 
  2899. elseif ( isset( $this->fields[ $field[ 'name' ] ] ) ) { 
  2900. $field = array_merge( $this->fields[ $field[ 'name' ] ], $field ); 
  2901.  
  2902. if ( pods_var_raw( 'hidden', $field, false, null, true ) ) 
  2903. $field[ 'type' ] = 'hidden'; 
  2904.  
  2905. $fields[ $field[ 'name' ] ] = $field; 
  2906.  
  2907. if ( empty( $this->id ) && null !== $default_value ) { 
  2908. $this->row_override[ $field[ 'name' ] ] = $default_value; 
  2909. elseif ( !empty( $this->id ) && null !== $value ) { 
  2910. $this->row[ $field[ 'name' ] ] = $value; 
  2911.  
  2912. unset( $form_fields ); // Cleanup 
  2913.  
  2914. $fields = $this->do_hook( 'form_fields', $fields, $params ); 
  2915.  
  2916. $label = $params[ 'label' ]; 
  2917.  
  2918. if ( empty( $label ) ) 
  2919. $label = __( 'Save Changes', 'pods' ); 
  2920.  
  2921. $thank_you = $params[ 'thank_you' ]; 
  2922. $fields_only = $params[ 'fields_only' ]; 
  2923.  
  2924. PodsForm::$form_counter++; 
  2925.  
  2926. ob_start(); 
  2927.  
  2928. if ( empty( $thank_you ) ) { 
  2929. $success = 'success'; 
  2930.  
  2931. if ( 1 < PodsForm::$form_counter ) 
  2932. $success .= PodsForm::$form_counter; 
  2933.  
  2934. $thank_you = pods_query_arg( array( 'success*' => null, $success => 1 ) ); 
  2935.  
  2936. if ( 1 == pods_v( $success, 'get', 0 ) ) { 
  2937. $message = __( 'Form submitted successfully', 'pods' ); 
  2938. /** 
  2939. * Change the text of the message that appears on succesful form submission. 
  2940. * @param string $message 
  2941. * @returns string the message 
  2942. * @since 3.0.0 
  2943. */ 
  2944. $message = apply_filters( 'pods_pod_form_success_message', $message ); 
  2945.  
  2946. echo '<div id="message" class="pods-form-front-success">' . $message . '</div>'; 
  2947.  
  2948. pods_view( PODS_DIR . 'ui/front/form.php', compact( array_keys( get_defined_vars() ) ) ); 
  2949.  
  2950. $output = ob_get_clean(); 
  2951.  
  2952. if ( empty( $this->id ) ) 
  2953. $this->row_override = array(); 
  2954.  
  2955. return $this->do_hook( 'form', $output, $fields, $label, $thank_you, $this, $this->id() ); 
  2956.  
  2957. /** 
  2958. * @param array $fields (optional) Fields to show in the view, defaults to all fields 
  2959. * @return mixed 
  2960. * @since 2.3.10 
  2961. */ 
  2962. public function view( $fields = null ) { 
  2963.  
  2964. $pod =& $this; 
  2965.  
  2966. // Convert comma separated list of fields to an array 
  2967. if ( null !== $fields && !is_array( $fields ) && 0 < strlen( $fields ) ) { 
  2968. $fields = explode( ', ', $fields ); 
  2969.  
  2970. $object_fields = (array) pods_v( 'object_fields', $this->pod_data, array(), true ); 
  2971.  
  2972. if ( empty( $fields ) ) { 
  2973. // Add core object fields if $fields is empty 
  2974. $fields = array_merge( $object_fields, $this->fields ); 
  2975.  
  2976. $view_fields = $fields; // Temporary 
  2977.  
  2978. $fields = array(); 
  2979.  
  2980. foreach ( $view_fields as $name => $field ) { 
  2981.  
  2982. $defaults = array( 
  2983. 'name' => $name 
  2984. ); 
  2985.  
  2986. if ( !is_array( $field ) ) { 
  2987. $name = $field; 
  2988.  
  2989. $field = array( 
  2990. 'name' => $name 
  2991. ); 
  2992.  
  2993. $field = array_merge( $defaults, $field ); 
  2994.  
  2995. $field[ 'name' ] = trim( $field[ 'name' ] ); 
  2996.  
  2997. if ( empty( $field[ 'name' ] ) ) { 
  2998. $field[ 'name' ] = trim( $name ); 
  2999.  
  3000. if ( isset( $object_fields[ $field[ 'name' ] ] ) ) 
  3001. $field = array_merge( $field, $object_fields[ $field[ 'name' ] ] ); 
  3002. elseif ( isset( $this->fields[ $field[ 'name' ] ] ) ) 
  3003. $field = array_merge( $this->fields[ $field[ 'name' ] ], $field ); 
  3004.  
  3005. if ( pods_v( 'hidden', $field, false, null, true ) || 'hidden' == $field[ 'type' ] ) { 
  3006. continue; 
  3007. elseif ( !PodsForm::permission( $field[ 'type' ], $field[ 'name' ], $field[ 'options' ], $fields, $pod, $pod->id() ) ) { 
  3008. continue; 
  3009.  
  3010. $fields[ $field[ 'name' ] ] = $field; 
  3011.  
  3012. unset( $view_fields ); // Cleanup 
  3013.  
  3014. $output = pods_view( PODS_DIR . 'ui/front/view.php', compact( array_keys( get_defined_vars() ) ), false, 'cache', true ); 
  3015.  
  3016. return $this->do_hook( 'view', $output, $fields, $this->id() ); 
  3017.  
  3018.  
  3019. /** 
  3020. * Replace magic tags with their values 
  3021. * @param string $code The content to evaluate 
  3022. * @param object $obj The Pods object 
  3023. * @return string Code with Magic Tags evaluated 
  3024. * @since 2.0 
  3025. */ 
  3026. public function do_magic_tags ( $code ) { 
  3027. return preg_replace_callback( '/({@(.*?)})/m', array( $this, 'process_magic_tags' ), $code ); 
  3028.  
  3029. /** 
  3030. * Replace magic tags with their values 
  3031. * @param string $tag The magic tag to process 
  3032. * @param object $obj The Pods object 
  3033. * @return string Code with Magic Tags evaluated 
  3034. * @since 2.0.2 
  3035. */ 
  3036. private function process_magic_tags ( $tag ) { 
  3037.  
  3038. if ( is_array( $tag ) ) { 
  3039. if ( !isset( $tag[ 2 ] ) && strlen( trim( $tag[ 2 ] ) ) < 1 ) 
  3040. return ''; 
  3041.  
  3042. $tag = $tag[ 2 ]; 
  3043.  
  3044. $tag = trim( $tag, ' {@}' ); 
  3045. $tag = explode( ', ', $tag ); 
  3046.  
  3047. if ( empty( $tag ) || !isset( $tag[ 0 ] ) || strlen( trim( $tag[ 0 ] ) ) < 1 ) 
  3048. return ''; 
  3049.  
  3050. foreach ( $tag as $k => $v ) { 
  3051. $tag[ $k ] = trim( $v ); 
  3052.  
  3053. $field_name = $tag[ 0 ]; 
  3054.  
  3055. $helper_name = $before = $after = ''; 
  3056.  
  3057. if ( isset( $tag[ 1 ] ) && !empty( $tag[ 1 ] ) ) { 
  3058. $value = $this->field( $field_name ); 
  3059.  
  3060. $helper_name = $tag[ 1 ]; 
  3061.  
  3062. $value = $this->helper( $helper_name, $value, $field_name ); 
  3063. else 
  3064. $value = $this->display( $field_name ); 
  3065.  
  3066. if ( isset( $tag[ 2 ] ) && !empty( $tag[ 2 ] ) ) 
  3067. $before = $tag[ 2 ]; 
  3068.  
  3069. if ( isset( $tag[ 3 ] ) && !empty( $tag[ 3 ] ) ) 
  3070. $after = $tag[ 3 ]; 
  3071.  
  3072. $value = apply_filters( 'pods_do_magic_tags', $value, $field_name, $helper_name, $before, $after ); 
  3073.  
  3074. if ( is_array( $value ) ) 
  3075. $value = pods_serial_comma( $value, array( 'field' => $field_name, 'fields' => $this->fields ) ); 
  3076.  
  3077. if ( null !== $value && false !== $value ) 
  3078. return $before . $value . $after; 
  3079.  
  3080. return ''; 
  3081.  
  3082. /** 
  3083. * Generate UI for Data Management 
  3084. * @param mixed $options Array or String containing Pod or Options to be used 
  3085. * @param bool $amend Whether to amend the default UI options or replace entirely 
  3086. * @return PodsUI|void UI object or void if custom UI used 
  3087. * @since 2.3.10 
  3088. */ 
  3089. public function ui ( $options = null, $amend = false ) { 
  3090. $num = ''; 
  3091.  
  3092. if ( empty( $options ) ) 
  3093. $options = array(); 
  3094. else { 
  3095. $num = pods_var( 'num', $options, '' ); 
  3096.  
  3097. if ( empty( $num ) ) { 
  3098. $num = ''; 
  3099.  
  3100. if ( $this->id() != pods_var( 'id' . $num, 'get', null, null, true ) ) 
  3101. $this->fetch( pods_var( 'id' . $num, 'get', null, null, true ) ); 
  3102.  
  3103. if ( !empty( $options ) && !$amend ) { 
  3104. $this->ui = $options; 
  3105.  
  3106. return pods_ui( $this ); 
  3107. elseif ( !empty( $options ) || 'custom' != pods_var( 'ui_style', $this->pod_data[ 'options' ], 'post_type', null, true ) ) { 
  3108. $actions_enabled = pods_var_raw( 'ui_actions_enabled', $this->pod_data[ 'options' ] ); 
  3109.  
  3110. if ( !empty( $actions_enabled ) ) 
  3111. $actions_enabled = (array) $actions_enabled; 
  3112. else 
  3113. $actions_enabled = array(); 
  3114.  
  3115. $available_actions = array( 
  3116. 'add',  
  3117. 'edit',  
  3118. 'duplicate',  
  3119. 'delete',  
  3120. 'reorder',  
  3121. 'export' 
  3122. ); 
  3123.  
  3124. if ( !empty( $actions_enabled ) ) { 
  3125. $actions_disabled = array( 
  3126. 'view' => 'view' 
  3127. ); 
  3128.  
  3129. foreach ( $available_actions as $action ) { 
  3130. if ( !in_array( $action, $actions_enabled ) ) 
  3131. $actions_disabled[ $action ] = $action; 
  3132. else { 
  3133. $actions_disabled = array( 
  3134. 'duplicate' => 'duplicate',  
  3135. 'view' => 'view',  
  3136. 'export' => 'export' 
  3137. ); 
  3138.  
  3139. if ( 1 == pods_var( 'ui_export', $this->pod_data[ 'options' ], 0 ) ) 
  3140. unset( $actions_disabled[ 'export' ] ); 
  3141.  
  3142. if ( empty( $options ) ) { 
  3143. $author_restrict = false; 
  3144.  
  3145. if ( isset( $this->fields[ 'author' ] ) && 'pick' == $this->fields[ 'author' ][ 'type' ] && 'user' == $this->fields[ 'author' ][ 'pick_object' ] ) 
  3146. $author_restrict = 'author.ID'; 
  3147.  
  3148. if ( !pods_is_admin( array( 'pods', 'pods_content' ) ) ) { 
  3149. if ( !current_user_can( 'pods_add_' . $this->pod ) ) { 
  3150. $actions_disabled[ 'add' ] = 'add'; 
  3151.  
  3152. if ( 'add' == pods_var( 'action' . $num, 'get' ) ) 
  3153. $_GET[ 'action' . $num ] = 'manage'; 
  3154.  
  3155. if ( !$author_restrict && !current_user_can( 'pods_edit_' . $this->pod ) && !current_user_can( 'pods_edit_others_' . $this->pod ) ) 
  3156. $actions_disabled[ 'edit' ] = 'edit'; 
  3157.  
  3158. if ( !$author_restrict && !current_user_can( 'pods_delete_' . $this->pod ) && !current_user_can( 'pods_delete_others_' . $this->pod ) ) 
  3159. $actions_disabled[ 'delete' ] = 'delete'; 
  3160.  
  3161. if ( !current_user_can( 'pods_reorder_' . $this->pod ) ) 
  3162. $actions_disabled[ 'reorder' ] = 'reorder'; 
  3163.  
  3164. if ( !current_user_can( 'pods_export_' . $this->pod ) ) 
  3165. $actions_disabled[ 'export' ] = 'export'; 
  3166.  
  3167. $_GET[ 'action' . $num ] = pods_var( 'action' . $num, 'get', pods_var( 'action', $options, 'manage' ) ); 
  3168.  
  3169. $index = $this->pod_data[ 'field_id' ]; 
  3170. $label = __( 'ID', 'pods' ); 
  3171.  
  3172. if ( isset( $this->pod_data[ 'fields' ][ $this->pod_data[ 'field_index' ] ] ) ) { 
  3173. $index = $this->pod_data[ 'field_index' ]; 
  3174. $label = $this->pod_data[ 'fields' ][ $this->pod_data[ 'field_index' ] ]; 
  3175.  
  3176. $manage = array( 
  3177. $index => $label 
  3178. ); 
  3179.  
  3180. if ( isset( $this->pod_data[ 'fields' ][ 'modified' ] ) ) 
  3181. $manage[ 'modified' ] = $this->pod_data[ 'fields' ][ 'modified' ][ 'label' ]; 
  3182.  
  3183. $manage_fields = pods_var_raw( 'ui_fields_manage', $this->pod_data[ 'options' ] ); 
  3184.  
  3185. if ( !empty( $manage_fields ) ) { 
  3186. $manage_new = array(); 
  3187.  
  3188. foreach ( $manage_fields as $manage_field ) { 
  3189. if ( isset( $this->pod_data[ 'fields' ][ $manage_field ] ) ) 
  3190. $manage_new[ $manage_field ] = $this->pod_data[ 'fields' ][ $manage_field ]; 
  3191. elseif ( isset( $this->pod_data[ 'object_fields' ][ $manage_field ] ) ) 
  3192. $manage_new[ $manage_field ] = $this->pod_data[ 'object_fields' ][ $manage_field ]; 
  3193. elseif ( $manage_field == $this->pod_data[ 'field_id' ] ) { 
  3194. $field = array( 
  3195. 'name' => $manage_field,  
  3196. 'label' => 'ID',  
  3197. 'type' => 'number',  
  3198. 'width' => '8%' 
  3199. ); 
  3200.  
  3201. $manage_new[ $manage_field ] = PodsForm::field_setup( $field, null, $field[ 'type' ] ); 
  3202.  
  3203. if ( !empty( $manage_new ) ) 
  3204. $manage = $manage_new; 
  3205.  
  3206. $manage = apply_filters( 'pods_admin_ui_fields_' . $this->pod, apply_filters( 'pods_admin_ui_fields', $manage, $this->pod, $this ), $this->pod, $this ); 
  3207.  
  3208. $icon = pods_var_raw( 'ui_icon', $this->pod_data[ 'options' ] ); 
  3209.  
  3210. if ( !empty( $icon ) ) 
  3211. $icon = pods_image_url( $icon, '32x32' ); 
  3212.  
  3213. $filters = pods_var_raw( 'ui_filters', $this->pod_data[ 'options' ] ); 
  3214.  
  3215. if ( !empty( $filters ) ) { 
  3216. $filters_new = array(); 
  3217.  
  3218. foreach ( $filters as $filter_field ) { 
  3219. if ( isset( $this->pod_data[ 'fields' ][ $filter_field ] ) ) 
  3220. $filters_new[ $filter_field ] = $this->pod_data[ 'fields' ][ $filter_field ]; 
  3221. elseif ( isset( $this->pod_data[ 'object_fields' ][ $filter_field ] ) ) 
  3222. $filters_new[ $filter_field ] = $this->pod_data[ 'object_fields' ][ $filter_field ]; 
  3223.  
  3224. $filters = $filters_new; 
  3225.  
  3226. $ui = array( 
  3227. 'fields' => array( 
  3228. 'manage' => $manage,  
  3229. 'add' => $this->pod_data[ 'fields' ],  
  3230. 'edit' => $this->pod_data[ 'fields' ],  
  3231. 'duplicate' => $this->pod_data[ 'fields' ] 
  3232. ),  
  3233. 'icon' => $icon,  
  3234. 'actions_disabled' => $actions_disabled 
  3235. ); 
  3236.  
  3237. if ( !empty( $filters ) ) { 
  3238. $ui[ 'fields' ][ 'search' ] = $filters; 
  3239. $ui[ 'filters' ] = array_keys( $filters ); 
  3240. $ui[ 'filters_enhanced' ] = true; 
  3241.  
  3242. $reorder_field = pods_var_raw( 'ui_reorder_field', $this->pod_data[ 'options' ] ); 
  3243.  
  3244. if ( in_array( 'reorder', $actions_enabled ) && !in_array( 'reorder', $actions_disabled ) && !empty( $reorder_field ) && ( ( !empty( $this->pod_data[ 'object_fields' ] ) && isset( $this->pod_data[ 'object_fields' ][ $reorder_field ] ) ) || isset( $this->pod_data[ 'fields' ][ $reorder_field ] ) ) ) { 
  3245. $ui[ 'reorder' ] = array( 'on' => $reorder_field ); 
  3246. $ui[ 'orderby' ] = $reorder_field; 
  3247. $ui[ 'orderby_dir' ] = 'ASC'; 
  3248.  
  3249. if ( !empty( $author_restrict ) ) 
  3250. $ui[ 'restrict' ] = array( 'author_restrict' => $author_restrict ); 
  3251.  
  3252. if ( !in_array( 'delete', $ui[ 'actions_disabled' ] ) ) { 
  3253. $ui[ 'actions_bulk' ] = array( 
  3254. 'delete' => array( 
  3255. 'label' => __( 'Delete', 'pods' ) 
  3256. // callback not needed, Pods has this built-in for delete 
  3257. ); 
  3258.  
  3259. $detail_url = pods_var( 'detail_url', $this->pod_data[ 'options' ] ); 
  3260.  
  3261. if ( 0 < strlen( $detail_url ) ) { 
  3262. $ui[ 'actions_custom' ] = array( 
  3263. 'view_url' => array( 
  3264. 'label' => 'View',  
  3265. 'link' => get_site_url() . '/' . $detail_url 
  3266. ); 
  3267.  
  3268. // @todo Customize the Add New / Manage links to point to their correct menu items 
  3269.  
  3270. $ui = apply_filters( 'pods_admin_ui_' . $this->pod, apply_filters( 'pods_admin_ui', $ui, $this->pod, $this ), $this->pod, $this ); 
  3271.  
  3272. // Override UI options 
  3273. foreach ( $options as $option => $value ) { 
  3274. $ui[ $option ] = $value; 
  3275.  
  3276. $this->ui = $ui; 
  3277.  
  3278. return pods_ui( $this ); 
  3279.  
  3280. do_action( 'pods_admin_ui_custom', $this ); 
  3281. do_action( 'pods_admin_ui_custom_' . $this->pod, $this ); 
  3282.  
  3283. /** 
  3284. * Handle filters / actions for the class 
  3285. * @see pods_do_hook 
  3286. * @return mixed Value filtered 
  3287. * @since 2.0 
  3288. */ 
  3289. private function do_hook () { 
  3290. $args = func_get_args(); 
  3291.  
  3292. if ( empty( $args ) ) 
  3293. return false; 
  3294.  
  3295. $name = array_shift( $args ); 
  3296.  
  3297. return pods_do_hook( 'pods', $name, $args, $this ); 
  3298.  
  3299. /** 
  3300. * Handle variables that have been deprecated and PodsData vars 
  3301. * @var $name 
  3302. * @return mixed 
  3303. * @since 2.0 
  3304. */ 
  3305. public function __get ( $name ) { 
  3306. $name = (string) $name; 
  3307.  
  3308. // PodsData vars 
  3309. if ( 0 === strpos( $name, 'field_' ) && isset( $this->data->{$name} ) ) { 
  3310. return $this->data->{$name}; 
  3311.  
  3312. if ( !isset( $this->deprecated ) ) { 
  3313. require_once( PODS_DIR . 'deprecated/classes/Pods.php' ); 
  3314. $this->deprecated = new Pods_Deprecated( $this ); 
  3315.  
  3316. $var = null; 
  3317.  
  3318. if ( isset( $this->deprecated->{$name} ) ) { 
  3319. if ( ! class_exists( 'Pod' ) || Pod::$deprecated_notice ) { 
  3320. pods_deprecated( "Pods->{$name}", '2.0' ); 
  3321.  
  3322. $var = $this->deprecated->{$name}; 
  3323. elseif ( ! class_exists( 'Pod' ) || Pod::$deprecated_notice ) { 
  3324. pods_deprecated( "Pods->{$name}", '2.0' ); 
  3325.  
  3326. return $var; 
  3327.  
  3328. /** 
  3329. * Handle methods that have been deprecated and any aliasing 
  3330. * @var $name 
  3331. * @var $args 
  3332. * @return mixed 
  3333. * @since 2.0 
  3334. */ 
  3335. public function __call ( $name, $args ) { 
  3336. $name = (string) $name; 
  3337.  
  3338. // select > find alias 
  3339. if ( 'select' == $name ) { 
  3340. return call_user_func_array( array( $this, 'find' ), $args ); 
  3341.  
  3342. if ( !isset( $this->deprecated ) ) { 
  3343. require_once( PODS_DIR . 'deprecated/classes/Pods.php' ); 
  3344. $this->deprecated = new Pods_Deprecated( $this ); 
  3345.  
  3346. if ( method_exists( $this->deprecated, $name ) ) { 
  3347. return call_user_func_array( array( $this->deprecated, $name ), $args ); 
  3348. elseif ( ! class_exists( 'Pod' ) || Pod::$deprecated_notice ) { 
  3349. pods_deprecated( "Pods::{$name}", '2.0' );