暫無描述

api-template.php 28KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416
  1. <?php
  2. /*
  3. * get_field()
  4. *
  5. * This function will return a custom field value for a specific field name/key + post_id.
  6. * There is a 3rd parameter to turn on/off formating. This means that an image field will not use
  7. * its 'return option' to format the value but return only what was saved in the database
  8. *
  9. * @type function
  10. * @since 3.6
  11. * @date 29/01/13
  12. *
  13. * @param $selector (string) the field name or key
  14. * @param $post_id (mixed) the post_id of which the value is saved against
  15. * @param $format_value (boolean) whether or not to format the value as described above
  16. * @return (mixed)
  17. */
  18. function get_field( $selector, $post_id = false, $format_value = true ) {
  19. // filter post_id
  20. $post_id = acf_get_valid_post_id( $post_id );
  21. // get field
  22. $field = acf_maybe_get_field( $selector, $post_id );
  23. // create dummy field
  24. if ( ! $field ) {
  25. $field = acf_get_valid_field(
  26. array(
  27. 'name' => $selector,
  28. 'key' => '',
  29. 'type' => '',
  30. )
  31. );
  32. // prevent formatting
  33. $format_value = false;
  34. }
  35. // get value for field
  36. $value = acf_get_value( $post_id, $field );
  37. // format value
  38. if ( $format_value ) {
  39. // get value for field
  40. $value = acf_format_value( $value, $post_id, $field );
  41. }
  42. // return
  43. return $value;
  44. }
  45. /*
  46. * the_field()
  47. *
  48. * This function is the same as echo get_field().
  49. *
  50. * @type function
  51. * @since 1.0.3
  52. * @date 29/01/13
  53. *
  54. * @param $selector (string) the field name or key
  55. * @param $post_id (mixed) the post_id of which the value is saved against
  56. * @return n/a
  57. */
  58. function the_field( $selector, $post_id = false, $format_value = true ) {
  59. $value = get_field( $selector, $post_id, $format_value );
  60. if ( is_array( $value ) ) {
  61. $value = @implode( ', ', $value );
  62. }
  63. echo $value;
  64. }
  65. /**
  66. * This function will return an array containing all the field data for a given field_name.
  67. *
  68. * @since 3.6
  69. * @date 3/02/13
  70. *
  71. * @param string $selector The field name or key.
  72. * @param mixed $post_id The post_id of which the value is saved against.
  73. * @param bool $format_value Whether to format the field value.
  74. * @param bool $load_value Whether to load the field value.
  75. *
  76. * @return array $field
  77. */
  78. function get_field_object( $selector, $post_id = false, $format_value = true, $load_value = true ) {
  79. // Compatibility with ACF ~4.
  80. if ( is_array( $format_value ) && isset( $format_value['format_value'] ) ) {
  81. $format_value = $format_value['format_value'];
  82. }
  83. $post_id = acf_get_valid_post_id( $post_id );
  84. $field = acf_maybe_get_field( $selector, $post_id );
  85. if ( ! $field ) {
  86. return false;
  87. }
  88. if ( $load_value ) {
  89. $field['value'] = acf_get_value( $post_id, $field );
  90. }
  91. if ( $format_value ) {
  92. $field['value'] = acf_format_value( $field['value'], $post_id, $field );
  93. }
  94. return $field;
  95. }
  96. /*
  97. * acf_get_object_field
  98. *
  99. * This function will return a field for the given selector.
  100. * It will also review the field_reference to ensure the correct field is returned which makes it useful for the template API
  101. *
  102. * @type function
  103. * @date 4/08/2015
  104. * @since 5.2.3
  105. *
  106. * @param $selector (mixed) identifyer of field. Can be an ID, key, name or post object
  107. * @param $post_id (mixed) the post_id of which the value is saved against
  108. * @param $strict (boolean) if true, return a field only when a field key is found.
  109. * @return $field (array)
  110. */
  111. function acf_maybe_get_field( $selector, $post_id = false, $strict = true ) {
  112. // init
  113. acf_init();
  114. // Check if field key was given.
  115. if ( acf_is_field_key( $selector ) ) {
  116. return acf_get_field( $selector );
  117. }
  118. // Lookup field via reference.
  119. $post_id = acf_get_valid_post_id( $post_id );
  120. $field = acf_get_meta_field( $selector, $post_id );
  121. if ( $field ) {
  122. return $field;
  123. }
  124. // Lookup field loosely via name.
  125. if ( ! $strict ) {
  126. return acf_get_field( $selector );
  127. }
  128. // Return no result.
  129. return false;
  130. }
  131. /*
  132. * acf_maybe_get_sub_field
  133. *
  134. * This function will attempt to find a sub field
  135. *
  136. * @type function
  137. * @date 3/10/2016
  138. * @since 5.4.0
  139. *
  140. * @param $post_id (int)
  141. * @return $post_id (int)
  142. */
  143. function acf_maybe_get_sub_field( $selectors, $post_id = false, $strict = true ) {
  144. // bail ealry if not enough selectors
  145. if ( ! is_array( $selectors ) || count( $selectors ) < 3 ) {
  146. return false;
  147. }
  148. // vars
  149. $offset = acf_get_setting( 'row_index_offset' );
  150. $selector = acf_extract_var( $selectors, 0 );
  151. $selectors = array_values( $selectors ); // reset keys
  152. // attempt get field
  153. $field = acf_maybe_get_field( $selector, $post_id, $strict );
  154. // bail early if no field
  155. if ( ! $field ) {
  156. return false;
  157. }
  158. // loop
  159. for ( $j = 0; $j < count( $selectors ); $j += 2 ) {
  160. // vars
  161. $sub_i = $selectors[ $j ];
  162. $sub_s = $selectors[ $j + 1 ];
  163. $field_name = $field['name'];
  164. // find sub field
  165. $field = acf_get_sub_field( $sub_s, $field );
  166. // bail early if no sub field
  167. if ( ! $field ) {
  168. return false;
  169. }
  170. // add to name
  171. $field['name'] = $field_name . '_' . ( $sub_i - $offset ) . '_' . $field['name'];
  172. }
  173. // return
  174. return $field;
  175. }
  176. /*
  177. * get_fields()
  178. *
  179. * This function will return an array containing all the custom field values for a specific post_id.
  180. * The function is not very elegant and wastes a lot of PHP memory / SQL queries if you are not using all the values.
  181. *
  182. * @type function
  183. * @since 3.6
  184. * @date 29/01/13
  185. *
  186. * @param $post_id (mixed) the post_id of which the value is saved against
  187. * @param $format_value (boolean) whether or not to format the field value
  188. * @return (array) associative array where field name => field value
  189. */
  190. function get_fields( $post_id = false, $format_value = true ) {
  191. // vars
  192. $fields = get_field_objects( $post_id, $format_value );
  193. $meta = array();
  194. // bail early
  195. if ( ! $fields ) {
  196. return false;
  197. }
  198. // populate
  199. foreach ( $fields as $k => $field ) {
  200. $meta[ $k ] = $field['value'];
  201. }
  202. // return
  203. return $meta;
  204. }
  205. /*
  206. * get_field_objects()
  207. *
  208. * This function will return an array containing all the custom field objects for a specific post_id.
  209. * The function is not very elegant and wastes a lot of PHP memory / SQL queries if you are not using all the fields / values.
  210. *
  211. * @type function
  212. * @since 3.6
  213. * @date 29/01/13
  214. *
  215. * @param $post_id (mixed) the post_id of which the value is saved against
  216. * @param $format_value (boolean) whether or not to format the field value
  217. * @param $load_value (boolean) whether or not to load the field value
  218. * @return (array) associative array where field name => field
  219. */
  220. function get_field_objects( $post_id = false, $format_value = true, $load_value = true ) {
  221. // init
  222. acf_init();
  223. // validate post_id
  224. $post_id = acf_get_valid_post_id( $post_id );
  225. // get meta
  226. $meta = acf_get_meta( $post_id );
  227. // bail early if no meta
  228. if ( empty( $meta ) ) {
  229. return false;
  230. }
  231. // populate vars
  232. $fields = array();
  233. foreach ( $meta as $key => $value ) {
  234. // bail if reference key does not exist
  235. if ( ! isset( $meta[ "_$key" ] ) ) {
  236. continue;
  237. }
  238. // get field
  239. $field = acf_get_field( $meta[ "_$key" ] );
  240. // bail early if no field, or if the field's name is different to $key
  241. // - solves problem where sub fields (and clone fields) are incorrectly allowed
  242. if ( ! $field || $field['name'] !== $key ) {
  243. continue;
  244. }
  245. // load value
  246. if ( $load_value ) {
  247. $field['value'] = acf_get_value( $post_id, $field );
  248. }
  249. // format value
  250. if ( $format_value ) {
  251. $field['value'] = acf_format_value( $field['value'], $post_id, $field );
  252. }
  253. // append to $value
  254. $fields[ $key ] = $field;
  255. }
  256. // no value
  257. if ( empty( $fields ) ) {
  258. return false;
  259. }
  260. // return
  261. return $fields;
  262. }
  263. /**
  264. * have_rows
  265. *
  266. * Checks if a field (such as Repeater or Flexible Content) has any rows of data to loop over.
  267. * This function is intended to be used in conjunction with the_row() to step through available values.
  268. *
  269. * @date 2/09/13
  270. * @since 4.3.0
  271. *
  272. * @param string $selector The field name or field key.
  273. * @param mixed $post_id The post ID where the value is saved. Defaults to the current post.
  274. * @return bool
  275. */
  276. function have_rows( $selector, $post_id = false ) {
  277. // Validate and backup $post_id.
  278. $_post_id = $post_id;
  279. $post_id = acf_get_valid_post_id( $post_id );
  280. // Vars.
  281. $key = "selector={$selector}/post_id={$post_id}";
  282. $active_loop = acf_get_loop( 'active' );
  283. $prev_loop = acf_get_loop( 'previous' );
  284. $new_loop = false;
  285. $sub_field = false;
  286. // Check if no active loop.
  287. if ( ! $active_loop ) {
  288. $new_loop = 'parent';
  289. // Detect "change" compared to the active loop.
  290. } elseif ( $key !== $active_loop['key'] ) {
  291. // Find sub field and check if a sub value exists.
  292. $sub_field_exists = false;
  293. $sub_field = acf_get_sub_field( $selector, $active_loop['field'] );
  294. if ( $sub_field ) {
  295. $sub_field_exists = isset( $active_loop['value'][ $active_loop['i'] ][ $sub_field['key'] ] );
  296. }
  297. // Detect change in post_id.
  298. if ( $post_id != $active_loop['post_id'] ) {
  299. // Case: Change in $post_id was due to this being a nested loop and not specifying the $post_id.
  300. // Action: Move down one level into a new loop.
  301. if ( empty( $_post_id ) && $sub_field_exists ) {
  302. $new_loop = 'child';
  303. // Case: Change in $post_id was due to a nested loop ending.
  304. // Action: move up one level through the loops.
  305. } elseif ( $prev_loop && $prev_loop['post_id'] == $post_id ) {
  306. acf_remove_loop( 'active' );
  307. $active_loop = $prev_loop;
  308. // Case: Chang in $post_id is the most obvious, used in an WP_Query loop with multiple $post objects.
  309. // Action: leave this current loop alone and create a new parent loop.
  310. } else {
  311. $new_loop = 'parent';
  312. }
  313. // Detect change in selector.
  314. } elseif ( $selector != $active_loop['selector'] ) {
  315. // Case: Change in $field_name was due to this being a nested loop.
  316. // Action: move down one level into a new loop.
  317. if ( $sub_field_exists ) {
  318. $new_loop = 'child';
  319. // Case: Change in $field_name was due to a nested loop ending.
  320. // Action: move up one level through the loops.
  321. } elseif ( $prev_loop && $prev_loop['selector'] == $selector && $prev_loop['post_id'] == $post_id ) {
  322. acf_remove_loop( 'active' );
  323. $active_loop = $prev_loop;
  324. // Case: Change in $field_name is the most obvious, this is a new loop for a different field within the $post.
  325. // Action: leave this current loop alone and create a new parent loop.
  326. } else {
  327. $new_loop = 'parent';
  328. }
  329. }
  330. }
  331. // Add loop if required.
  332. if ( $new_loop ) {
  333. $args = array(
  334. 'key' => $key,
  335. 'selector' => $selector,
  336. 'post_id' => $post_id,
  337. 'name' => null,
  338. 'value' => null,
  339. 'field' => null,
  340. 'i' => -1,
  341. );
  342. // Case: Parent loop.
  343. if ( $new_loop === 'parent' ) {
  344. $field = get_field_object( $selector, $post_id, false );
  345. if ( $field ) {
  346. $args['field'] = $field;
  347. $args['value'] = $field['value'];
  348. $args['name'] = $field['name'];
  349. unset( $args['field']['value'] );
  350. }
  351. // Case: Child loop ($sub_field must exist).
  352. } else {
  353. $args['field'] = $sub_field;
  354. $args['value'] = $active_loop['value'][ $active_loop['i'] ][ $sub_field['key'] ];
  355. $args['name'] = "{$active_loop['name']}_{$active_loop['i']}_{$sub_field['name']}";
  356. $args['post_id'] = $active_loop['post_id'];
  357. }
  358. // Bail early if value is either empty or a non array.
  359. if ( ! $args['value'] || ! is_array( $args['value'] ) ) {
  360. return false;
  361. }
  362. // Allow for non repeatable data for Group and Clone fields.
  363. if ( acf_get_field_type_prop( $args['field']['type'], 'have_rows' ) === 'single' ) {
  364. $args['value'] = array( $args['value'] );
  365. }
  366. // Add loop.
  367. $active_loop = acf_add_loop( $args );
  368. }
  369. // Return true if next row exists.
  370. if ( $active_loop && isset( $active_loop['value'][ $active_loop['i'] + 1 ] ) ) {
  371. return true;
  372. }
  373. // Return false if no next row.
  374. acf_remove_loop( 'active' );
  375. return false;
  376. }
  377. /*
  378. * the_row
  379. *
  380. * This function will progress the global repeater or flexible content value 1 row
  381. *
  382. * @type function
  383. * @date 2/09/13
  384. * @since 4.3.0
  385. *
  386. * @param N/A
  387. * @return (array) the current row data
  388. */
  389. function the_row( $format = false ) {
  390. // vars
  391. $i = acf_get_loop( 'active', 'i' );
  392. // increase
  393. $i++;
  394. // update
  395. acf_update_loop( 'active', 'i', $i );
  396. // return
  397. return get_row( $format );
  398. }
  399. function get_row( $format = false ) {
  400. // vars
  401. $loop = acf_get_loop( 'active' );
  402. // bail early if no loop
  403. if ( ! $loop ) {
  404. return false;
  405. }
  406. // get value
  407. $value = acf_maybe_get( $loop['value'], $loop['i'] );
  408. // bail early if no current value
  409. // possible if get_row_layout() is called before the_row()
  410. if ( ! $value ) {
  411. return false;
  412. }
  413. // format
  414. if ( $format ) {
  415. // vars
  416. $field = $loop['field'];
  417. // single row
  418. if ( acf_get_field_type_prop( $field['type'], 'have_rows' ) === 'single' ) {
  419. // format value
  420. $value = acf_format_value( $value, $loop['post_id'], $field );
  421. // multiple rows
  422. } else {
  423. // format entire value
  424. // - solves problem where cached value is incomplete
  425. // - no performance issues here thanks to cache
  426. $value = acf_format_value( $loop['value'], $loop['post_id'], $field );
  427. $value = acf_maybe_get( $value, $loop['i'] );
  428. }
  429. }
  430. // return
  431. return $value;
  432. }
  433. function get_row_index() {
  434. // vars
  435. $i = acf_get_loop( 'active', 'i' );
  436. $offset = acf_get_setting( 'row_index_offset' );
  437. // return
  438. return $offset + $i;
  439. }
  440. function the_row_index() {
  441. echo get_row_index();
  442. }
  443. /*
  444. * get_row_sub_field
  445. *
  446. * This function is used inside a 'has_sub_field' while loop to return a sub field object
  447. *
  448. * @type function
  449. * @date 16/05/2016
  450. * @since 5.3.8
  451. *
  452. * @param $selector (string)
  453. * @return (array)
  454. */
  455. function get_row_sub_field( $selector ) {
  456. // vars
  457. $row = acf_get_loop( 'active' );
  458. // bail early if no row
  459. if ( ! $row ) {
  460. return false;
  461. }
  462. // attempt to find sub field
  463. $sub_field = acf_get_sub_field( $selector, $row['field'] );
  464. // bail early if no field
  465. if ( ! $sub_field ) {
  466. return false;
  467. }
  468. // update field's name based on row data
  469. $sub_field['name'] = "{$row['name']}_{$row['i']}_{$sub_field['name']}";
  470. // return
  471. return $sub_field;
  472. }
  473. /*
  474. * get_row_sub_value
  475. *
  476. * This function is used inside a 'has_sub_field' while loop to return a sub field value
  477. *
  478. * @type function
  479. * @date 16/05/2016
  480. * @since 5.3.8
  481. *
  482. * @param $selector (string)
  483. * @return (mixed)
  484. */
  485. function get_row_sub_value( $selector ) {
  486. // vars
  487. $row = acf_get_loop( 'active' );
  488. // bail early if no row
  489. if ( ! $row ) {
  490. return null;
  491. }
  492. // return value
  493. if ( isset( $row['value'][ $row['i'] ][ $selector ] ) ) {
  494. return $row['value'][ $row['i'] ][ $selector ];
  495. }
  496. // return
  497. return null;
  498. }
  499. /*
  500. * reset_rows
  501. *
  502. * This function will find the current loop and unset it from the global array.
  503. * To bo used when loop finishes or a break is used
  504. *
  505. * @type function
  506. * @date 26/10/13
  507. * @since 5.0.0
  508. *
  509. * @param $hard_reset (boolean) completely wipe the global variable, or just unset the active row
  510. * @return (boolean)
  511. */
  512. function reset_rows() {
  513. // remove last loop
  514. acf_remove_loop( 'active' );
  515. // return
  516. return true;
  517. }
  518. /*
  519. * has_sub_field()
  520. *
  521. * This function is used inside a while loop to return either true or false (loop again or stop).
  522. * When using a repeater or flexible content field, it will loop through the rows until
  523. * there are none left or a break is detected
  524. *
  525. * @type function
  526. * @since 1.0.3
  527. * @date 29/01/13
  528. *
  529. * @param $field_name (string) the field name
  530. * @param $post_id (mixed) the post_id of which the value is saved against
  531. * @return (boolean)
  532. */
  533. function has_sub_field( $field_name, $post_id = false ) {
  534. // vars
  535. $r = have_rows( $field_name, $post_id );
  536. // if has rows, progress through 1 row for the while loop to work
  537. if ( $r ) {
  538. the_row();
  539. }
  540. // return
  541. return $r;
  542. }
  543. function has_sub_fields( $field_name, $post_id = false ) {
  544. return has_sub_field( $field_name, $post_id );
  545. }
  546. /*
  547. * get_sub_field()
  548. *
  549. * This function is used inside a 'has_sub_field' while loop to return a sub field value
  550. *
  551. * @type function
  552. * @since 1.0.3
  553. * @date 29/01/13
  554. *
  555. * @param $field_name (string) the field name
  556. * @return (mixed)
  557. */
  558. function get_sub_field( $selector = '', $format_value = true ) {
  559. // get sub field
  560. $sub_field = get_sub_field_object( $selector, $format_value );
  561. // bail early if no sub field
  562. if ( ! $sub_field ) {
  563. return false;
  564. }
  565. // return
  566. return $sub_field['value'];
  567. }
  568. /*
  569. * the_sub_field()
  570. *
  571. * This function is the same as echo get_sub_field
  572. *
  573. * @type function
  574. * @since 1.0.3
  575. * @date 29/01/13
  576. *
  577. * @param $field_name (string) the field name
  578. * @return n/a
  579. */
  580. function the_sub_field( $field_name, $format_value = true ) {
  581. $value = get_sub_field( $field_name, $format_value );
  582. if ( is_array( $value ) ) {
  583. $value = implode( ', ', $value );
  584. }
  585. echo $value;
  586. }
  587. /*
  588. * get_sub_field_object()
  589. *
  590. * This function is used inside a 'has_sub_field' while loop to return a sub field object
  591. *
  592. * @type function
  593. * @since 3.5.8.1
  594. * @date 29/01/13
  595. *
  596. * @param $child_name (string) the field name
  597. * @return (array)
  598. */
  599. function get_sub_field_object( $selector, $format_value = true, $load_value = true ) {
  600. // vars
  601. $row = acf_get_loop( 'active' );
  602. // bail early if no row
  603. if ( ! $row ) {
  604. return false;
  605. }
  606. // attempt to find sub field
  607. $sub_field = get_row_sub_field( $selector );
  608. // bail early if no sub field
  609. if ( ! $sub_field ) {
  610. return false;
  611. }
  612. // load value
  613. if ( $load_value ) {
  614. $sub_field['value'] = get_row_sub_value( $sub_field['key'] );
  615. }
  616. // format value
  617. if ( $format_value ) {
  618. // get value for field
  619. $sub_field['value'] = acf_format_value( $sub_field['value'], $row['post_id'], $sub_field );
  620. }
  621. // return
  622. return $sub_field;
  623. }
  624. /*
  625. * get_row_layout()
  626. *
  627. * This function will return a string representation of the current row layout within a 'have_rows' loop
  628. *
  629. * @type function
  630. * @since 3.0.6
  631. * @date 29/01/13
  632. *
  633. * @param n/a
  634. * @return (string)
  635. */
  636. function get_row_layout() {
  637. // vars
  638. $row = get_row();
  639. // return
  640. if ( isset( $row['acf_fc_layout'] ) ) {
  641. return $row['acf_fc_layout'];
  642. }
  643. // return
  644. return false;
  645. }
  646. /**
  647. * This function is used to add basic shortcode support for the ACF plugin
  648. * eg. [acf field="heading" post_id="123" format_value="1"]
  649. *
  650. * @since 1.1.1
  651. * @date 29/01/13
  652. *
  653. * @param array $atts The shortcode attributes.
  654. *
  655. * @return string
  656. */
  657. function acf_shortcode( $atts ) {
  658. // Mitigate issue where some AJAX requests can return ACF field data.
  659. $capability = apply_filters( 'acf/ajax/shortcode_capability', 'edit_posts' );
  660. if ( wp_doing_ajax() && ( $capability !== false ) && ! current_user_can( $capability ) ) {
  661. return;
  662. }
  663. $atts = shortcode_atts(
  664. array(
  665. 'field' => '',
  666. 'post_id' => false,
  667. 'format_value' => true,
  668. ),
  669. $atts,
  670. 'acf'
  671. );
  672. $access_already_prevented = apply_filters( 'acf/prevent_access_to_unknown_fields', false );
  673. $filter_applied = false;
  674. if ( ! $access_already_prevented ) {
  675. $filter_applied = true;
  676. add_filter( 'acf/prevent_access_to_unknown_fields', '__return_true' );
  677. }
  678. // Try to get the field value.
  679. $value = get_field( $atts['field'], $atts['post_id'], $atts['format_value'] );
  680. if ( $filter_applied ) {
  681. remove_filter( 'acf/prevent_access_to_unknown_fields', '__return_true' );
  682. }
  683. if ( is_array( $value ) ) {
  684. $value = @implode( ', ', $value );
  685. }
  686. return $value;
  687. }
  688. add_shortcode( 'acf', 'acf_shortcode' );
  689. /*
  690. * update_field()
  691. *
  692. * This function will update a value in the database
  693. *
  694. * @type function
  695. * @since 3.1.9
  696. * @date 29/01/13
  697. *
  698. * @param $selector (string) the field name or key
  699. * @param $value (mixed) the value to save in the database
  700. * @param $post_id (mixed) the post_id of which the value is saved against
  701. * @return (boolean)
  702. */
  703. function update_field( $selector, $value, $post_id = false ) {
  704. // filter post_id
  705. $post_id = acf_get_valid_post_id( $post_id );
  706. // get field
  707. $field = acf_maybe_get_field( $selector, $post_id, false );
  708. // create dummy field
  709. if ( ! $field ) {
  710. $field = acf_get_valid_field(
  711. array(
  712. 'name' => $selector,
  713. 'key' => '',
  714. 'type' => '',
  715. )
  716. );
  717. }
  718. // save
  719. return acf_update_value( $value, $post_id, $field );
  720. }
  721. /*
  722. * update_sub_field
  723. *
  724. * This function will update a value of a sub field in the database
  725. *
  726. * @type function
  727. * @date 2/04/2014
  728. * @since 5.0.0
  729. *
  730. * @param $selector (mixed) the sub field name or key, or an array of ancestors
  731. * @param $value (mixed) the value to save in the database
  732. * @param $post_id (mixed) the post_id of which the value is saved against
  733. * @return (boolean)
  734. */
  735. function update_sub_field( $selector, $value, $post_id = false ) {
  736. // vars
  737. $sub_field = false;
  738. // get sub field
  739. if ( is_array( $selector ) ) {
  740. $post_id = acf_get_valid_post_id( $post_id );
  741. $sub_field = acf_maybe_get_sub_field( $selector, $post_id, false );
  742. } else {
  743. $post_id = acf_get_loop( 'active', 'post_id' );
  744. $sub_field = get_row_sub_field( $selector );
  745. }
  746. // bail early if no sub field
  747. if ( ! $sub_field ) {
  748. return false;
  749. }
  750. // update
  751. return acf_update_value( $value, $post_id, $sub_field );
  752. }
  753. /*
  754. * delete_field()
  755. *
  756. * This function will remove a value from the database
  757. *
  758. * @type function
  759. * @since 3.1.9
  760. * @date 29/01/13
  761. *
  762. * @param $selector (string) the field name or key
  763. * @param $post_id (mixed) the post_id of which the value is saved against
  764. * @return (boolean)
  765. */
  766. function delete_field( $selector, $post_id = false ) {
  767. // filter post_id
  768. $post_id = acf_get_valid_post_id( $post_id );
  769. // get field
  770. $field = acf_maybe_get_field( $selector, $post_id );
  771. // delete
  772. return $field ? acf_delete_value( $post_id, $field ) : false;
  773. }
  774. /*
  775. * delete_sub_field
  776. *
  777. * This function will delete a value of a sub field in the database
  778. *
  779. * @type function
  780. * @date 2/04/2014
  781. * @since 5.0.0
  782. *
  783. * @param $selector (mixed) the sub field name or key, or an array of ancestors
  784. * @param $value (mixed) the value to save in the database
  785. * @param $post_id (mixed) the post_id of which the value is saved against
  786. * @return (boolean)
  787. */
  788. function delete_sub_field( $selector, $post_id = false ) {
  789. return update_sub_field( $selector, null, $post_id );
  790. }
  791. /*
  792. * add_row
  793. *
  794. * This function will add a row of data to a field
  795. *
  796. * @type function
  797. * @date 16/10/2015
  798. * @since 5.2.3
  799. *
  800. * @param $selector (string)
  801. * @param $row (array)
  802. * @param $post_id (mixed)
  803. * @return (boolean)
  804. */
  805. function add_row( $selector, $row = false, $post_id = false ) {
  806. // filter post_id
  807. $post_id = acf_get_valid_post_id( $post_id );
  808. // get field
  809. $field = acf_maybe_get_field( $selector, $post_id, false );
  810. // bail early if no field
  811. if ( ! $field ) {
  812. return false;
  813. }
  814. // get raw value
  815. $value = acf_get_value( $post_id, $field );
  816. // ensure array
  817. $value = acf_get_array( $value );
  818. // append
  819. $value[] = $row;
  820. // update value
  821. acf_update_value( $value, $post_id, $field );
  822. // return
  823. return count( $value );
  824. }
  825. /*
  826. * add_sub_row
  827. *
  828. * This function will add a row of data to a field
  829. *
  830. * @type function
  831. * @date 16/10/2015
  832. * @since 5.2.3
  833. *
  834. * @param $selector (string)
  835. * @param $row (array)
  836. * @param $post_id (mixed)
  837. * @return (boolean)
  838. */
  839. function add_sub_row( $selector, $row = false, $post_id = false ) {
  840. // vars
  841. $sub_field = false;
  842. // get sub field
  843. if ( is_array( $selector ) ) {
  844. $post_id = acf_get_valid_post_id( $post_id );
  845. $sub_field = acf_maybe_get_sub_field( $selector, $post_id, false );
  846. } else {
  847. $post_id = acf_get_loop( 'active', 'post_id' );
  848. $sub_field = get_row_sub_field( $selector );
  849. }
  850. // bail early if no sub field
  851. if ( ! $sub_field ) {
  852. return false;
  853. }
  854. // get raw value
  855. $value = acf_get_value( $post_id, $sub_field );
  856. // ensure array
  857. $value = acf_get_array( $value );
  858. // append
  859. $value[] = $row;
  860. // update
  861. acf_update_value( $value, $post_id, $sub_field );
  862. // return
  863. return count( $value );
  864. }
  865. /*
  866. * update_row
  867. *
  868. * This function will update a row of data to a field
  869. *
  870. * @type function
  871. * @date 19/10/2015
  872. * @since 5.2.3
  873. *
  874. * @param $selector (string)
  875. * @param $i (int)
  876. * @param $row (array)
  877. * @param $post_id (mixed)
  878. * @return (boolean)
  879. */
  880. function update_row( $selector, $i = 1, $row = false, $post_id = false ) {
  881. // vars
  882. $offset = acf_get_setting( 'row_index_offset' );
  883. $i = $i - $offset;
  884. // filter post_id
  885. $post_id = acf_get_valid_post_id( $post_id );
  886. // get field
  887. $field = acf_maybe_get_field( $selector, $post_id, false );
  888. // bail early if no field
  889. if ( ! $field ) {
  890. return false;
  891. }
  892. // get raw value
  893. $value = acf_get_value( $post_id, $field );
  894. // ensure array
  895. $value = acf_get_array( $value );
  896. // update
  897. $value[ $i ] = $row;
  898. // update value
  899. acf_update_value( $value, $post_id, $field );
  900. // return
  901. return true;
  902. }
  903. /*
  904. * update_sub_row
  905. *
  906. * This function will add a row of data to a field
  907. *
  908. * @type function
  909. * @date 16/10/2015
  910. * @since 5.2.3
  911. *
  912. * @param $selector (string)
  913. * @param $row (array)
  914. * @param $post_id (mixed)
  915. * @return (boolean)
  916. */
  917. function update_sub_row( $selector, $i = 1, $row = false, $post_id = false ) {
  918. // vars
  919. $sub_field = false;
  920. $offset = acf_get_setting( 'row_index_offset' );
  921. $i = $i - $offset;
  922. // get sub field
  923. if ( is_array( $selector ) ) {
  924. $post_id = acf_get_valid_post_id( $post_id );
  925. $sub_field = acf_maybe_get_sub_field( $selector, $post_id, false );
  926. } else {
  927. $post_id = acf_get_loop( 'active', 'post_id' );
  928. $sub_field = get_row_sub_field( $selector );
  929. }
  930. // bail early if no sub field
  931. if ( ! $sub_field ) {
  932. return false;
  933. }
  934. // get raw value
  935. $value = acf_get_value( $post_id, $sub_field );
  936. // ensure array
  937. $value = acf_get_array( $value );
  938. // append
  939. $value[ $i ] = $row;
  940. // update
  941. acf_update_value( $value, $post_id, $sub_field );
  942. // return
  943. return true;
  944. }
  945. /*
  946. * delete_row
  947. *
  948. * This function will delete a row of data from a field
  949. *
  950. * @type function
  951. * @date 19/10/2015
  952. * @since 5.2.3
  953. *
  954. * @param $selector (string)
  955. * @param $i (int)
  956. * @param $post_id (mixed)
  957. * @return (boolean)
  958. */
  959. function delete_row( $selector, $i = 1, $post_id = false ) {
  960. // vars
  961. $offset = acf_get_setting( 'row_index_offset' );
  962. $i = $i - $offset;
  963. // filter post_id
  964. $post_id = acf_get_valid_post_id( $post_id );
  965. // get field
  966. $field = acf_maybe_get_field( $selector, $post_id );
  967. // bail early if no field
  968. if ( ! $field ) {
  969. return false;
  970. }
  971. // get value
  972. $value = acf_get_value( $post_id, $field );
  973. // ensure array
  974. $value = acf_get_array( $value );
  975. // bail early if index doesn't exist
  976. if ( ! isset( $value[ $i ] ) ) {
  977. return false;
  978. }
  979. // unset
  980. unset( $value[ $i ] );
  981. // update
  982. acf_update_value( $value, $post_id, $field );
  983. // return
  984. return true;
  985. }
  986. /*
  987. * delete_sub_row
  988. *
  989. * This function will add a row of data to a field
  990. *
  991. * @type function
  992. * @date 16/10/2015
  993. * @since 5.2.3
  994. *
  995. * @param $selector (string)
  996. * @param $row (array)
  997. * @param $post_id (mixed)
  998. * @return (boolean)
  999. */
  1000. function delete_sub_row( $selector, $i = 1, $post_id = false ) {
  1001. // vars
  1002. $sub_field = false;
  1003. $offset = acf_get_setting( 'row_index_offset' );
  1004. $i = $i - $offset;
  1005. // get sub field
  1006. if ( is_array( $selector ) ) {
  1007. $post_id = acf_get_valid_post_id( $post_id );
  1008. $sub_field = acf_maybe_get_sub_field( $selector, $post_id, false );
  1009. } else {
  1010. $post_id = acf_get_loop( 'active', 'post_id' );
  1011. $sub_field = get_row_sub_field( $selector );
  1012. }
  1013. // bail early if no sub field
  1014. if ( ! $sub_field ) {
  1015. return false;
  1016. }
  1017. // get raw value
  1018. $value = acf_get_value( $post_id, $sub_field );
  1019. // ensure array
  1020. $value = acf_get_array( $value );
  1021. // bail early if index doesn't exist
  1022. if ( ! isset( $value[ $i ] ) ) {
  1023. return false;
  1024. }
  1025. // append
  1026. unset( $value[ $i ] );
  1027. // update
  1028. acf_update_value( $value, $post_id, $sub_field );
  1029. // return
  1030. return true;
  1031. }
  1032. /*
  1033. * Depreceated Functions
  1034. *
  1035. * These functions are outdated
  1036. *
  1037. * @type function
  1038. * @date 4/03/2014
  1039. * @since 1.0.0
  1040. *
  1041. * @param n/a
  1042. * @return n/a
  1043. */
  1044. function create_field( $field ) {
  1045. acf_render_field( $field );
  1046. }
  1047. function render_field( $field ) {
  1048. acf_render_field( $field );
  1049. }
  1050. function reset_the_repeater_field() {
  1051. return reset_rows();
  1052. }
  1053. function the_repeater_field( $field_name, $post_id = false ) {
  1054. return has_sub_field( $field_name, $post_id );
  1055. }
  1056. function the_flexible_field( $field_name, $post_id = false ) {
  1057. return has_sub_field( $field_name, $post_id );
  1058. }
  1059. function acf_filter_post_id( $post_id ) {
  1060. return acf_get_valid_post_id( $post_id );
  1061. }