PageRenderTime 28ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/membership/app/model/class-ms-model-customposttype.php

https://gitlab.com/najomie/fit-hippie
PHP | 471 lines | 179 code | 51 blank | 241 comment | 14 complexity | c21996466b71926e2e34fd0f88b71bd1 MD5 | raw file
  1. <?php
  2. /**
  3. * Abstract Custom Post Type model.
  4. *
  5. * Persists data into wp_post and wp_postmeta
  6. *
  7. * @since 1.0.0
  8. *
  9. * @package Membership2
  10. * @subpackage Model
  11. */
  12. class MS_Model_CustomPostType extends MS_Model {
  13. /**
  14. * Model custom post type.
  15. *
  16. * Both static and class property are used to handle php 5.2 limitations.
  17. * Override this value in child object.
  18. *
  19. * @since 1.0.0
  20. * @var string
  21. */
  22. protected static $POST_TYPE = '';
  23. /**
  24. * ID of the model object.
  25. *
  26. * Saved as WP post ID.
  27. *
  28. * @since 1.0.0
  29. *
  30. * @var int
  31. */
  32. protected $id = 0;
  33. /**
  34. * Model name (this is the post slug)
  35. *
  36. * @since 1.0.0
  37. *
  38. * @var string
  39. */
  40. protected $name = '';
  41. /**
  42. * Model title.
  43. *
  44. * Saved in $post->post_title.
  45. *
  46. * @since 1.0.0
  47. *
  48. * @var string
  49. */
  50. protected $title = '';
  51. /**
  52. * Model description.
  53. *
  54. * Saved in $post->post_content and $post->excerpt.
  55. *
  56. * @since 1.0.0
  57. *
  58. * @var string
  59. */
  60. protected $description = '';
  61. /**
  62. * The user ID of the owner.
  63. *
  64. * Saved in $post->post_author
  65. *
  66. * @since 1.0.0
  67. *
  68. * @var int
  69. */
  70. protected $user_id = 0;
  71. /**
  72. * The last modified date.
  73. *
  74. * Saved in $post->post_modified
  75. *
  76. * @since 1.0.0
  77. *
  78. * @var string
  79. */
  80. protected $post_modified = '';
  81. /**
  82. * Custom data can be used by other plugins via the set_custom_data() and
  83. * get_custom_data() functions.
  84. *
  85. * This can be used to store data that other plugins use to store object
  86. * related information, like affiliate options for a membership, etc.
  87. *
  88. * @since 1.0.0
  89. *
  90. * @var array
  91. */
  92. protected $custom_data = array();
  93. /**
  94. * Not persisted fields.
  95. *
  96. * @since 1.0.0
  97. *
  98. * @var array
  99. */
  100. static public $ignore_fields = array();
  101. /**
  102. * Validates the object right after it was loaded/initialized.
  103. *
  104. * We ensure that the custom_data field is an array.
  105. *
  106. * @since 1.0.0
  107. */
  108. public function prepare_obj() {
  109. parent::prepare_obj();
  110. if ( ! is_array( $this->custom_data ) ) {
  111. $this->custom_data = array();
  112. }
  113. }
  114. /**
  115. * Save content in wp tables (wp_post and wp_postmeta).
  116. *
  117. * Update WP cache.
  118. *
  119. * @since 1.0.0
  120. */
  121. public function save() {
  122. MS_Factory::select_blog();
  123. $this->before_save();
  124. $this->post_modified = MS_Helper_Period::current_date( 'Y-m-d H:i:s' );
  125. $class = get_class( $this );
  126. /*
  127. * Serialize data that is later saved to the postmeta table.
  128. *
  129. * While data is serialized it can also modify the model data before
  130. * writing it to the posts table.
  131. */
  132. $data = MS_Factory::serialize_model( $this );
  133. $post = array(
  134. 'comment_status' => 'closed',
  135. 'ping_status' => 'closed',
  136. 'post_author' => $this->user_id,
  137. 'post_content' => $this->description,
  138. 'post_excerpt' => $this->description,
  139. 'post_name' => sanitize_text_field( $this->name ),
  140. 'post_status' => 'private',
  141. 'post_title' => sanitize_title( ! empty( $this->title ) ? $this->title : $this->name ),
  142. 'post_type' => $this->get_post_type(),
  143. 'post_modified' => $this->post_modified,
  144. );
  145. /**
  146. * Give child classes an easy way to modify the post and meta data right
  147. * before it is saved.
  148. *
  149. * @since 1.0.1.0
  150. */
  151. $post = $this->save_post_data( $post );
  152. $data = $this->save_meta_data( $data );
  153. if ( empty( $this->id ) ) {
  154. $this->id = wp_insert_post( $post );
  155. } else {
  156. $post[ 'ID' ] = $this->id;
  157. wp_update_post( $post );
  158. }
  159. // We first remove any metadata of our custom post type that is not
  160. // contained in the serialized data collection.
  161. $this->clean_metadata( array_keys( $data ) );
  162. // Then we update all meta fields that are inside the collection
  163. foreach ( $data as $field => $val ) {
  164. update_post_meta( $this->id, $field, $val );
  165. }
  166. wp_cache_set( $this->id, $this, $class );
  167. $this->after_save();
  168. MS_Factory::revert_blog();
  169. global $wp_current_filter;
  170. if ( ! in_array( 'ms_saved_' . $class, $wp_current_filter ) ) {
  171. /**
  172. * Action triggered after a custom post type model was saved to
  173. * database.
  174. *
  175. * @since 1.0.0
  176. */
  177. do_action( 'ms_saved_' . $class, $this );
  178. }
  179. }
  180. /**
  181. * Prepare the post data right before it is saved to the wp_posts table.
  182. *
  183. * @see self::save()
  184. * @since 1.0.1.0
  185. * @param array $post Data collection passed to wp_update_post().
  186. * @return array Data collection passed to wp_update_post().
  187. */
  188. protected function save_post_data( $post ) {
  189. return $post;
  190. }
  191. /**
  192. * Prepare the meta data right before it is saved to the wp_postmeta table.
  193. *
  194. * @see self::save()
  195. * @since 1.0.1.0
  196. * @param array $data Key-Value pairs that represent metadata.
  197. * @return array Key-Value pairs that represent metadata.
  198. */
  199. protected function save_meta_data( $data ) {
  200. return $data;
  201. }
  202. /**
  203. * Populate the model with custom data from the wp_posts table.
  204. *
  205. * @see MS_Factory::load_from_wp_custom_post_type()
  206. * @since 1.0.1.0
  207. * @param array $post Data collection passed to wp_update_post().
  208. */
  209. public function load_post_data( $post ) {
  210. }
  211. /**
  212. * Populate the model with custom data from the wp_postmeta table.
  213. *
  214. * @see MS_Factory::load_from_wp_custom_post_type()
  215. * @since 1.0.1.0
  216. * @param array $data Key-Value pairs that represent metadata.
  217. */
  218. public function load_meta_data( $data ) {
  219. }
  220. /**
  221. * Delete post from wp table
  222. *
  223. * @since 1.0.0
  224. *
  225. * @return bool
  226. */
  227. public function delete() {
  228. MS_Factory::select_blog();
  229. do_action( 'MS_Model_CustomPostType_delete_before', $this );
  230. $res = false;
  231. if ( ! empty( $this->id ) ) {
  232. $res = ( false !== wp_delete_post( $this->id, true ) );
  233. }
  234. do_action( 'MS_Model_CustomPostType_delete_after', $this, $res );
  235. MS_Factory::revert_blog();
  236. return $res;
  237. }
  238. /**
  239. * Removes all meta fields, except the ones that are specified in the
  240. * second parameter.
  241. *
  242. * @since 1.0.0
  243. * @param array $data_to_keep List of meta-fields to keep (field-names)
  244. */
  245. private function clean_metadata( $data_to_keep ) {
  246. global $wpdb;
  247. $sql = "SELECT meta_key FROM {$wpdb->postmeta} WHERE post_id = %s;";
  248. $sql = $wpdb->prepare( $sql, $this->id );
  249. $all_fields = $wpdb->get_col( $sql );
  250. $remove = array_diff( $all_fields, $data_to_keep );
  251. $remove = apply_filters(
  252. 'ms_model_clean_metadata',
  253. $remove,
  254. $all_fields,
  255. $this->id,
  256. $data_to_keep
  257. );
  258. foreach ( $remove as $key ) {
  259. delete_post_meta( $this->id, $key );
  260. }
  261. }
  262. /**
  263. * Get custom register post type args for this model.
  264. *
  265. * @since 1.0.0
  266. */
  267. public static function get_register_post_type_args() {
  268. return apply_filters(
  269. 'ms_customposttype_register_args',
  270. array()
  271. );
  272. }
  273. /**
  274. * Check to see if the post is currently being edited.
  275. *
  276. * @see wp_check_post_lock.
  277. *
  278. * @since 1.0.0
  279. *
  280. * @return boolean True if locked.
  281. */
  282. public function check_object_lock() {
  283. MS_Factory::select_blog();
  284. $locked = false;
  285. if ( $this->is_valid()
  286. && $lock = get_post_meta( $this->id, '_ms_edit_lock', true )
  287. ) {
  288. $time = $lock;
  289. $time_window = apply_filters(
  290. 'MS_Model_CustomPostType_check_object_lock_window',
  291. 150
  292. );
  293. if ( $time && $time > time() - $time_window ) {
  294. $locked = true;
  295. }
  296. }
  297. MS_Factory::revert_blog();
  298. return apply_filters(
  299. 'MS_Model_CustomPostType_check_object_lock',
  300. $locked,
  301. $this
  302. );
  303. }
  304. /**
  305. * Mark the object as currently being edited.
  306. *
  307. * Based in the wp_set_post_lock
  308. *
  309. * @since 1.0.0
  310. *
  311. * @return bool|int
  312. */
  313. public function set_object_lock() {
  314. MS_Factory::select_blog();
  315. $lock = false;
  316. if ( $this->is_valid() ) {
  317. $lock = apply_filters(
  318. 'MS_Model_CustomPostType_set_object_lock',
  319. time()
  320. );
  321. update_post_meta( $this->id, '_ms_edit_lock', $lock );
  322. }
  323. MS_Factory::revert_blog();
  324. return apply_filters(
  325. 'MS_Model_CustomPostType_set_object_lock',
  326. $lock,
  327. $this
  328. );
  329. }
  330. /**
  331. * Delete object lock.
  332. *
  333. * @since 1.0.0
  334. */
  335. public function delete_object_lock() {
  336. MS_Factory::select_blog();
  337. if ( $this->is_valid() ) {
  338. update_post_meta( $this->id, '_ms_edit_lock', '' );
  339. }
  340. do_action( 'MS_Model_CustomPostType_delete_object_lock', $this );
  341. MS_Factory::revert_blog();
  342. }
  343. /**
  344. * Check if the current post type exists.
  345. *
  346. * @since 1.0.0
  347. *
  348. * @return boolean True if valid.
  349. */
  350. public function is_valid() {
  351. $valid = false;
  352. if ( $this->id > 0 ) {
  353. $valid = true;
  354. }
  355. return apply_filters(
  356. 'MS_Model_CustomPostType_is_valid',
  357. $valid,
  358. $this
  359. );
  360. }
  361. /**
  362. * Either creates or updates the value of a custom data field.
  363. *
  364. * Note: Remember to prefix the $key with a unique string to prevent
  365. * conflicts with other plugins that also use this function.
  366. *
  367. * @since 1.0.0
  368. * @api
  369. *
  370. * @param string $key The field-key.
  371. * @param mixed $value The new value to assign to the field.
  372. */
  373. public function set_custom_data( $key, $value ) {
  374. $this->custom_data[ $key ] = $value;
  375. }
  376. /**
  377. * Removes a custom data field from this object.
  378. *
  379. * @since 1.0.0
  380. * @api
  381. *
  382. * @param string $key The field-key.
  383. */
  384. public function delete_custom_data( $key ) {
  385. unset( $this->custom_data[ $key ] );
  386. }
  387. /**
  388. * Returns the value of a custom data field.
  389. *
  390. * @since 1.0.0
  391. * @api
  392. *
  393. * @param string $key The field-key.
  394. * @return mixed The value that was previously assigned to the custom field
  395. * or false if no value was set for the field.
  396. */
  397. public function get_custom_data( $key ) {
  398. $res = false;
  399. if ( isset( $this->custom_data[ $key ] ) ) {
  400. $res = $this->custom_data[ $key ];
  401. }
  402. return $res;
  403. }
  404. /**
  405. * Returns the post-type of the current object.
  406. *
  407. * @since 1.0.0
  408. * @return string The post-type name.
  409. */
  410. protected static function _post_type( $orig_posttype ) {
  411. // Post-type is always lower case.
  412. $posttype = strtolower( substr( $orig_posttype, 0, 20 ) );
  413. // Network-wide mode uses different post-types then single-site mode.
  414. if ( MS_Plugin::is_network_wide() ) {
  415. $posttype = substr( $posttype, 0, 18 );
  416. $posttype .= '-n';
  417. }
  418. return $posttype;
  419. }
  420. }