/app/model/class-ms-model-pages.php

  1. <?php 
  2. /** 
  3. * @copyright Incsub (http://incsub.com/) 
  4. * 
  5. * @license http://opensource.org/licenses/GPL-2.0 GNU General Public License, version 2 (GPL-2.0) 
  6. * 
  7. * This program is free software; you can redistribute it and/or modify 
  8. * it under the terms of the GNU General Public License, version 2, as 
  9. * published by the Free Software Foundation. 
  10. * 
  11. * This program is distributed in the hope that it will be useful,  
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of 
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
  14. * GNU General Public License for more details. 
  15. * 
  16. * You should have received a copy of the GNU General Public License 
  17. * along with this program; if not, write to the Free Software 
  18. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,  
  19. * MA 02110-1301 USA 
  20. * 
  21. */ 
  22.  
  23. /** 
  24. * Plugin Pages model. 
  25. * 
  26. * Main MS Pages class, contains any Membership page functions. 
  27. * 
  28. * @since 1.0.0 
  29. * 
  30. * @package Membership2 
  31. * @subpackage Model 
  32. */ 
  33. class MS_Model_Pages extends MS_Model_Option { 
  34.  
  35. /** 
  36. * Singleton instance. 
  37. * 
  38. * @since 1.0.0 
  39. * 
  40. * @staticvar MS_Model_Settings 
  41. */ 
  42. public static $instance; 
  43.  
  44. /** 
  45. * Plugin pages constants. 
  46. * 
  47. * @since 1.0.0 
  48. * 
  49. * @var string 
  50. */ 
  51. const MS_PAGE_MEMBERSHIPS = 'memberships'; 
  52. const MS_PAGE_PROTECTED_CONTENT = 'protected-content'; 
  53. const MS_PAGE_ACCOUNT = 'account'; 
  54. const MS_PAGE_REGISTER = 'register'; 
  55. const MS_PAGE_REG_COMPLETE = 'registration-complete'; 
  56.  
  57. /** 
  58. * Association between membership page-types and WordPress post_ids. 
  59. * 
  60. * @since 1.0.4.5 
  61. * 
  62. * @var array 
  63. */ 
  64. public $settings = array(); 
  65.  
  66. /** 
  67. * Returns the singleton instance of the MS_Model_Pages object 
  68. * 
  69. * @since 1.1.0 
  70. * @return MS_Model_Pages 
  71. */ 
  72. static public function get_model() { 
  73. static $Model = null; 
  74.  
  75. if ( null === $Model ) { 
  76. $Model = MS_Factory::load( 'MS_Model_Pages' ); 
  77.  
  78. return $Model; 
  79.  
  80. /** 
  81. * Returns a MS_Model_Pages setting value (these are the association between 
  82. * our Membership Page types and WordPress posts) 
  83. * 
  84. * @since 1.0.4.5 
  85. * @param string $key The setting key. 
  86. * @return any The setting value. A post_id or 0. 
  87. */ 
  88. static public function get_setting( $key ) { 
  89. $model = self::get_model(); 
  90.  
  91. if ( ! isset( $model->settings[ $key ] ) ) { 
  92. $model->settings[$key] = 0; 
  93.  
  94. return apply_filters( 
  95. 'ms_model_pages_get_setting',  
  96. $model->settings[$key],  
  97. $key 
  98. ); 
  99.  
  100. /** 
  101. * Saves a MS_Model_Pages setting value. 
  102. * 
  103. * @since 1.0.4.5 
  104. * @param string $key The setting key. 
  105. * @param any $value The new setting value. 
  106. */ 
  107. static public function set_setting( $key, $value ) { 
  108. $model = self::get_model(); 
  109.  
  110. $value = apply_filters( 
  111. 'ms_model_pages_set_setting',  
  112. $value,  
  113. $key 
  114. ); 
  115.  
  116. $model->settings[$key] = $value; 
  117. $model->save(); 
  118.  
  119. /** 
  120. * Get MS Page types 
  121. * 
  122. * @since 1.0.0 
  123. * 
  124. * @return array{ 
  125. * @type string $page_type The ms page type. 
  126. * @type string $title The page type title. 
  127. * } 
  128. */ 
  129. static public function get_page_types() { 
  130. static $Page_types; 
  131.  
  132. if ( empty( $Page_types ) ) { 
  133. $Page_types = array( 
  134. self::MS_PAGE_MEMBERSHIPS => __( 'Memberships', MS_TEXT_DOMAIN ),  
  135. self::MS_PAGE_PROTECTED_CONTENT => __( 'Protected Content', MS_TEXT_DOMAIN ),  
  136. self::MS_PAGE_REGISTER => __( 'Register', MS_TEXT_DOMAIN ),  
  137. self::MS_PAGE_REG_COMPLETE => __( 'Registration Complete', MS_TEXT_DOMAIN ),  
  138. self::MS_PAGE_ACCOUNT => __( 'Account', MS_TEXT_DOMAIN ),  
  139. ); 
  140.  
  141. $Page_types = apply_filters( 
  142. 'ms_model_pages_get_page_types',  
  143. $Page_types 
  144. ); 
  145.  
  146. return $Page_types; 
  147.  
  148. /** 
  149. * Returns a longer description for a page-type 
  150. * 
  151. * @since 1.1.0 
  152. * @param string $type The page-type 
  153. * @return string The full description 
  154. */ 
  155. static public function get_description( $type ) { 
  156. static $Description = null; 
  157.  
  158. if ( null === $Description ) { 
  159. $Description = array( 
  160. self::MS_PAGE_MEMBERSHIPS => __( 'A list with all public memberships.', MS_TEXT_DOMAIN ),  
  161. self::MS_PAGE_PROTECTED_CONTENT => __( 'Displayed when a user cannot access the requested page.', MS_TEXT_DOMAIN ),  
  162. self::MS_PAGE_REGISTER => __( 'Guests can register a new account here.', MS_TEXT_DOMAIN ),  
  163. self::MS_PAGE_REG_COMPLETE => __( 'Thank you page after registration is completed.', MS_TEXT_DOMAIN ),  
  164. self::MS_PAGE_ACCOUNT => __( 'Shows details about the current user.', MS_TEXT_DOMAIN ),  
  165. ); 
  166.  
  167. $Description = apply_filters( 
  168. 'ms_model_pages_get_description',  
  169. $Description 
  170. ); 
  171.  
  172. if ( ! isset( $Description[$type] ) ) { 
  173. $Description[$type] = ''; 
  174.  
  175. return $Description[$type]; 
  176.  
  177.  
  178. /** 
  179. * Validate ms page type. 
  180. * 
  181. * @since 1.0.0 
  182. * 
  183. * @param string $type The page type to validate. 
  184. * @return boolean True if valid. 
  185. */ 
  186. static public function is_valid_type( $type ) { 
  187. static $Res = array(); 
  188.  
  189. if ( ! isset( $Res[$type] ) ) { 
  190. $Res[$type] = array_key_exists( $type, self::get_page_types() ); 
  191.  
  192. $Res[$type] = apply_filters( 
  193. 'ms_model_pages_is_valid_type',  
  194. $Res[$type] 
  195. ); 
  196.  
  197. return $Res[$type]; 
  198.  
  199. /** 
  200. * Get MS Pages. 
  201. * 
  202. * @since 1.0.0 
  203. * 
  204. * @return WP_Post[] The page model objects. 
  205. */ 
  206. static public function get_pages() { 
  207. static $Pages = null; 
  208.  
  209. if ( null === $Pages ) { 
  210. $Pages = array(); 
  211. $page_types = self::get_page_types(); 
  212.  
  213. $site_id = self::get_setting( 'site_id' ); 
  214. MS_Factory::select_blog( $site_id ); 
  215.  
  216. foreach ( $page_types as $page_type => $title ) { 
  217. $page_id = self::get_setting( $page_type ); 
  218. if ( empty( $page_id ) ) { continue; } 
  219.  
  220. $the_page = get_post( $page_id ); 
  221. if ( empty ( $the_page ) ) { continue; } 
  222.  
  223. $Pages[$page_type] = apply_filters( 
  224. 'ms_model_pages_get_pages_item',  
  225. $the_page,  
  226. $page_type,  
  227. $page_id 
  228. ); 
  229.  
  230. MS_Factory::revert_blog(); 
  231.  
  232. $Pages = apply_filters( 
  233. 'ms_model_pages_get_pages',  
  234. $Pages 
  235. ); 
  236.  
  237. return $Pages; 
  238.  
  239. /** 
  240. * Get specific MS Page. 
  241. * 
  242. * @since 1.0.0 
  243. * 
  244. * @param string $page_type The page type to retrieve the page. 
  245. * @return WP_Post The page model object. 
  246. */ 
  247. static public function get_page( $page_type ) { 
  248. $result = null; 
  249.  
  250. if ( self::is_valid_type( $page_type ) ) { 
  251. // Get a list of all WP_Post items. 
  252. $pages = self::get_pages(); 
  253.  
  254. if ( ! empty( $pages[ $page_type ] ) ) { 
  255. $result = $pages[ $page_type ]; 
  256. } else { 
  257. MS_Helper_Debug::log( 'ms_model_pages_get_page error: invalid page type: ' . $page_type ); 
  258.  
  259. return apply_filters( 
  260. 'ms_model_pages_get_page',  
  261. $result 
  262. ); 
  263.  
  264. /** 
  265. * Get specific MS Page using either ID or slug information. 
  266. * 
  267. * @since 1.0.4.4 
  268. * 
  269. * @param string $field The field to check. [id|slug] 
  270. * @param string $value The field value 
  271. * @return null|WP_Post The page object. 
  272. */ 
  273. static public function get_page_by( $field, $value ) { 
  274. static $Page_list = array(); 
  275.  
  276. if ( ! isset( $Page_list[$field] ) ) { 
  277. $Page_list[$field] = array(); 
  278.  
  279. if ( ! isset( $Page_list[$field][ $value ] ) ) { 
  280. $page_found = null; 
  281.  
  282. switch ( $field ) { 
  283. case 'id': $value = absint( $value ); break; 
  284.  
  285. $ms_pages = self::get_pages(); 
  286. $found = false; 
  287.  
  288. foreach ( $ms_pages as $type => $page ) { 
  289. switch ( $field ) { 
  290. case 'id': $found = ($value === absint( $page->ID ) ); break; 
  291. case 'slug': $found = ($value === $page->post_name ); break; 
  292.  
  293. if ( $found ) { 
  294. $page_found = $page; 
  295. break; 
  296.  
  297. $Page_list[$field][ $value ] = apply_filters( 
  298. 'ms_model_pages_get_page_by_id',  
  299. $page_found,  
  300. $field,  
  301. $value 
  302. ); 
  303.  
  304. return $Page_list[$field][ $value ]; 
  305.  
  306. /** 
  307. * Returns the page_id that is identified by the specified filter. 
  308. * Filter can be either a type-name, post-ID or WP_Post (in that order) 
  309. * 
  310. * @since 1.1.0 
  311. * @param mixed $filter The filter to translate into a post_id 
  312. * @return int 
  313. */ 
  314. static public function get_page_id( $filter ) { 
  315. $page_id = 0; 
  316.  
  317. if ( is_string( $filter ) ) { 
  318. $filter = self::get_page( $filter ); 
  319. } elseif ( is_numeric( $filter ) ) { 
  320. $page_id = $filter; 
  321.  
  322. if ( is_a( $filter, 'WP_Post' ) ) { 
  323. $page_id = $filter->ID; 
  324.  
  325. return apply_filters( 
  326. 'ms_model_pages_get_page_id',  
  327. $page_id,  
  328. $filter 
  329. ); 
  330.  
  331. /** 
  332. * Returns details about the site that contains the Membership2 pages on 
  333. * a network-wide protected network. 
  334. * 
  335. * It will always return current-site data if protection is site-wide. 
  336. * 
  337. * Possible keys: 
  338. * - all keys available in get_bloginfo() 
  339. * 
  340. * @since 2.0.0 
  341. * @param string $key The detail to return. See info for possible values. 
  342. * @return string The requested detail about the site. 
  343. */ 
  344. static public function get_site_info( $key ) { 
  345. static $Site_Info = null; 
  346.  
  347. // On first call get the site-ID and general site-details. 
  348. if ( null === $Site_Info ) { 
  349. $Site_Info = array(); 
  350.  
  351. $site_id = get_current_blog_id(); 
  352.  
  353. $Site_Info['id'] = $site_id; 
  354.  
  355. // If a blog-specific setting was requested we lazy-load it now. 
  356. if ( ! isset( $Site_Info[$key] ) ) { 
  357. switch_to_blog( $Site_Info['id'] ); 
  358. $Site_Info[$key] = get_bloginfo( $key ); 
  359. restore_current_blog(); 
  360.  
  361. return $Site_Info[$key]; 
  362.  
  363. /** 
  364. * Checks if the current URL is a MS Page. 
  365. * If yes, then some basic information on this page are returned. 
  366. * 
  367. * @since 1.0.4.4 
  368. * @param int $page_id Optional. The page_id to fetch. 
  369. * @return WP_Post|null 
  370. */ 
  371. static public function current_page( $page_id = false, $page_type = null ) { 
  372. static $Res = array(); 
  373. $key = json_encode( $page_id ) . json_encode( $page_type ); 
  374.  
  375. if ( ! isset( $Res[$key] ) ) { 
  376. $this_page = null; 
  377. $site_id = self::get_site_info( 'id' ); 
  378.  
  379. if ( $site_id == get_current_blog_id() ) { 
  380. if ( ! empty( $page_type ) ) { 
  381. /** 
  382. * We have a page_type: 
  383. * Get infos of that page! 
  384. */ 
  385. $expected_page = self::get_page( $page_type ); 
  386.  
  387. if ( $page_id == $expected_page->ID ) { 
  388. $this_page = $expected_page; 
  389. } else { 
  390. /** 
  391. * We don't have the page_type: 
  392. * Use current page_id or the specified page_id/slug! 
  393. */ 
  394. if ( empty( $page_id ) ) { $page_id = get_the_ID(); } 
  395. if ( empty( $page_id ) ) { $page_id = get_queried_object_id(); } 
  396. if ( empty( $page_id ) && did_action( 'setup_theme' ) ) { 
  397. $url = lib2()->net->current_url(); 
  398. $page_id = url_to_postid( $url ); 
  399.  
  400. if ( ! empty( $page_id ) ) { 
  401. if ( is_numeric( $page_id ) ) { 
  402. $this_page = self::get_page_by( 'id', $page_id ); 
  403. } else { 
  404. $this_page = self::get_page_by( 'slug', $page_id ); 
  405.  
  406. $Res[$key] = apply_filters( 
  407. 'ms_model_pages_current_page',  
  408. $this_page 
  409. ); 
  410.  
  411. return $Res[$key]; 
  412.  
  413. /** 
  414. * Verify if is a MS Page. 
  415. * 
  416. * Verify if current page, or passed page_id is a plugin special page. 
  417. * 
  418. * @since 1.0.0 
  419. * 
  420. * @param int $page_id Optional. The page id to verify. Default to current page. 
  421. * @param string $page_type Optional. The page type to verify. If null, test it against all ms pages. 
  422. */ 
  423. static public function is_membership_page( $page_id = null, $page_type = null ) { 
  424. $ms_page_type = false; 
  425. $page = self::current_page( $page_id ); 
  426.  
  427. $site_id = self::get_site_info( 'id' ); 
  428.  
  429. if ( $site_id == get_current_blog_id() ) { 
  430. if ( empty( $page_type ) ) { 
  431. if ( $page ) { 
  432. $ms_page_type = self::get_page_type( $page->ID ); 
  433. } else { 
  434. if ( empty( $page_id ) && is_page() ) { 
  435. $page_id = get_the_ID(); 
  436.  
  437. if ( ! empty( $page_id ) ) { 
  438. $ms_page = self::get_page( $page_type ); 
  439. if ( $page_id == $ms_page->id ) { 
  440. $ms_page_type = $page_type; 
  441.  
  442. return apply_filters( 
  443. 'ms_model_pages_is_membership_page',  
  444. $ms_page_type 
  445. ); 
  446.  
  447. /** 
  448. * Get MS Page URL. 
  449. * 
  450. * @since 1.0.0 
  451. * 
  452. * @param string|WP_Post $page_type The page type name or a WP_Post object. 
  453. * @param boolean $ssl If wanted a SSL url. Set to null to use auto detection. 
  454. * @return string The MS Page URL. 
  455. */ 
  456. static public function get_page_url( $page_type, $ssl = null ) { 
  457. static $Urls = array(); 
  458.  
  459. $site_id = self::get_site_info( 'id' ); 
  460. $page_id = self::get_page_id( $page_type ); 
  461.  
  462. if ( ! isset( $Urls[$page_id] ) ) { 
  463. if ( is_multisite() ) { 
  464. $url = get_blog_permalink( $site_id, $page_id ); 
  465. } else { 
  466. $url = get_permalink( $page_id ); 
  467.  
  468. if ( null === $ssl ) { $ssl = is_ssl(); } 
  469. if ( $ssl ) { 
  470. $url = MS_Helper_Utility::get_ssl_url( $url ); 
  471.  
  472. $Urls[$page_id] = apply_filters( 
  473. 'ms_model_pages_get_ms_page_url',  
  474. $url,  
  475. $page_type,  
  476. $ssl 
  477. ); 
  478.  
  479. return $Urls[$page_id]; 
  480.  
  481. /** 
  482. * Redirect the user the specified membership page. 
  483. * 
  484. * @since 1.1.1.4 
  485. * @param string $page_type The page-type. 
  486. * @param array $args Optional. Additional URL parameters. 
  487. */ 
  488. static public function redirect_to( $page_type, $args = array() ) { 
  489. self::create_missing_pages(); 
  490. $url = self::get_page_url( $page_type ); 
  491.  
  492. $url = esc_url_raw( add_query_arg( $args, $url ) ); 
  493.  
  494. /** 
  495. * Opportunity for other plugins to redirect to a different page. 
  496. */ 
  497. $url = apply_filters( 
  498. 'ms_model_pages_redirect_to',  
  499. $url,  
  500. $page_type,  
  501. $args 
  502. ); 
  503.  
  504. wp_safe_redirect( $url ); 
  505. exit; 
  506.  
  507. /** 
  508. * Returns the URL to display after successful login. 
  509. * 
  510. * @since 1.1.0 
  511. * 
  512. * @param bool $filter Optional. If set to false then the URL is not 
  513. * filtered and the default value is returned. 
  514. * @return string URL of the page to display after login. 
  515. */ 
  516. static public function get_url_after_login( $filter = true ) { 
  517. if ( isset( $_REQUEST['redirect_to'] ) ) { 
  518. $url = $_REQUEST['redirect_to']; 
  519. $enforce = true; // This redirection was enforced via REUQEST param. 
  520. } else { 
  521. $url = self::get_page_url( self::MS_PAGE_ACCOUNT ); 
  522. $enforce = false; // This is the default redirection. 
  523.  
  524. if ( $filter ) { 
  525. $url = apply_filters( 
  526. 'ms_url_after_login',  
  527. $url,  
  528. $enforce 
  529. ); 
  530.  
  531. return $url; 
  532.  
  533. /** 
  534. * Returns the URL to display after successful logout. 
  535. * 
  536. * @since 1.1.0 
  537. * 
  538. * @param bool $filter Optional. If set to false then the URL is not 
  539. * filtered and the default value is returned. 
  540. * @return string URL of the page to display after logout. 
  541. */ 
  542. static public function get_url_after_logout( $filter = true ) { 
  543. if ( isset( $_REQUEST['redirect_to'] ) ) { 
  544. $url = $_REQUEST['redirect_to']; 
  545. $enforce = true; // This redirection was enforced via REUQEST param. 
  546. } else { 
  547. $url = home_url( '/' ); 
  548. $enforce = false; // This is the default redirection. 
  549.  
  550. if ( $filter ) { 
  551. $url = apply_filters( 
  552. 'ms_url_after_logout',  
  553. $url,  
  554. $enforce 
  555. ); 
  556.  
  557. return $url; 
  558.  
  559. /** 
  560. * Get MS Page type by ID. 
  561. * 
  562. * @since 1.1.0 
  563. * 
  564. * @param string|WP_Post $page_type The page type name or a WP_Post object. 
  565. * @return string The MS Page type name. 
  566. */ 
  567. static public function get_page_type( $page_id ) { 
  568. static $Types = array(); 
  569.  
  570. $page_id = self::get_page_id( $page_id ); 
  571. $pages = self::get_pages(); 
  572.  
  573. if ( ! isset( $Types[$page_id] ) ) { 
  574. $type = ''; 
  575. foreach ( $pages as $page_type => $page ) { 
  576. if ( $page->ID === $page_id ) { 
  577. $type = $page_type; 
  578. break; 
  579.  
  580. $Types[$page_id] = apply_filters( 
  581. 'ms_model_pages_get_ms_page_type',  
  582. $type,  
  583. $page_id 
  584. ); 
  585.  
  586. return $Types[$page_id]; 
  587.  
  588. /** 
  589. * Creates any missing Membership pages. 
  590. * 
  591. * @since 1.1.0 
  592. * @return array|false Titles of the created pages 
  593. */ 
  594. static public function create_missing_pages() { 
  595. static $Done = false; 
  596. $res = false; 
  597.  
  598. if ( $Done ) { return $res; } 
  599. $Done = true; 
  600.  
  601. $user_id = get_current_user_id(); 
  602. if ( empty( $user_id ) ) { return $res; } 
  603.  
  604. $types = self::get_page_types(); 
  605.  
  606. $res = array(); 
  607.  
  608. $site_id = self::get_setting( 'site_id' ); 
  609. MS_Factory::select_blog( $site_id ); 
  610.  
  611. foreach ( $types as $type => $title ) { 
  612. $page_id = self::get_setting( $type ); 
  613. $status = get_post_status( $page_id ); 
  614.  
  615. if ( ! $status || 'trash' == $status ) { 
  616. // Page does not exist or was deleted. Create new page. 
  617. $page_id = 0; 
  618. } elseif ( 'publish' != $status ) { 
  619. // The page exists but is not published. Publish now. 
  620. wp_publish_post( $page_id ); 
  621.  
  622. // If the post_id does not exist then create a new page 
  623. if ( empty( $page_id ) ) { 
  624. $data = array( 
  625. 'post_title' => $title,  
  626. 'post_name' => $type,  
  627. 'post_content' => self::get_default_content( $type ),  
  628. 'post_type' => 'page',  
  629. 'post_status' => 'publish',  
  630. 'post_author' => $user_id,  
  631. ); 
  632. $new_id = wp_insert_post( $data ); 
  633.  
  634. /** 
  635. * Filter the new page_id 
  636. * 
  637. * @since 1.1.0 
  638. */ 
  639. $new_id = apply_filters( 
  640. 'ms_model_pages_create_missing_page',  
  641. $new_id,  
  642. $type,  
  643. $data 
  644. ); 
  645.  
  646. if ( is_numeric( $new_id ) ) { 
  647. self::set_setting( $type, $new_id ); 
  648. $res[$new_id] = $title; 
  649.  
  650. /** 
  651. * Trigger action to allow modifications to the page 
  652. * 
  653. * @since 1.1.0 
  654. */ 
  655. do_action( 
  656. 'ms_model_pages_create_wp_page',  
  657. $new_id 
  658. ); 
  659. MS_Factory::revert_blog(); 
  660.  
  661. return apply_filters( 
  662. 'ms_model_pages_create_missing_page',  
  663. $res 
  664. ); 
  665.  
  666. /** 
  667. * Returns true only then, when the current user can edit menu items. 
  668. * 
  669. * Reasons why it might be denied: 
  670. * - There are no menus where items can be added to. 
  671. * - The user is no admin. 
  672. * 
  673. * @since 1.1.0 
  674. * @return bool 
  675. */ 
  676. static public function can_edit_menus() { 
  677. $Can_Edit_Menus = null; 
  678.  
  679. if ( null === $Can_Edit_Menus ) { 
  680. $Can_Edit_Menus = false; 
  681.  
  682. if ( ! MS_Plugin::is_network_wide() ) { 
  683. $menus = wp_get_nav_menus(); 
  684.  
  685. if ( MS_Model_Member::is_admin_user() && ! empty( $menus ) ) { 
  686. $Can_Edit_Menus = true; 
  687.  
  688. $Can_Edit_Menus = apply_filters( 
  689. 'ms_model_pages_can_edit_menus',  
  690. $Can_Edit_Menus 
  691. ); 
  692.  
  693. return $Can_Edit_Menus; 
  694.  
  695. /** 
  696. * Create MS Pages in Menus. 
  697. * 
  698. * @since 1.0.0 
  699. * 
  700. * @param string $page_type The page type to create menu. 
  701. * @param string $update_only Only used by the upgrade class. 
  702. * @param string $type Only used by the upgrade class. 
  703. * @return bool True means that at least one menu item was created. 
  704. */ 
  705. static public function create_menu( $page_type, $update_only = null, $update_type = null ) { 
  706. $res = false; 
  707.  
  708. if ( self::is_valid_type( $page_type ) ) { 
  709. if ( $update_only && empty( $update_type ) ) { 
  710. self::create_menu( $page_type, true, 'page' ); 
  711. self::create_menu( $page_type, true, 'ms_page' ); 
  712. } else { 
  713. $ms_page = self::get_page( $page_type, true ); 
  714. $navs = wp_get_nav_menus( array( 'orderby' => 'name' ) ); 
  715.  
  716. if ( ! empty( $navs ) ) { 
  717. $object_type = empty( $update_type ) ? 'page' : $update_type; 
  718. $page_url = self::get_page_url( $ms_page ); 
  719.  
  720. foreach ( $navs as $nav ) { 
  721. $args['meta_query'] = array( 
  722. array( 
  723. 'key' => '_menu_item_object_id',  
  724. 'value' => $ms_page->ID,  
  725. ),  
  726. array( 
  727. 'key' => '_menu_item_object',  
  728. 'value' => $object_type,  
  729. ),  
  730. array( 
  731. 'key' => '_menu_item_type',  
  732. 'value' => 'post_type',  
  733. ),  
  734. ); 
  735.  
  736. // Search for existing menu item and create it if not found 
  737. $items = wp_get_nav_menu_items( $nav, $args ); 
  738.  
  739. $menu_item = apply_filters( 
  740. 'ms_model_settings_create_menu_item',  
  741. array( 
  742. 'menu-item-object-id' => $ms_page->ID,  
  743. 'menu-item-object' => 'page',  
  744. 'menu-item-parent-id' => 0,  
  745. 'menu-item-position' => 0,  
  746. 'menu-item-type' => 'post_type',  
  747. 'menu-item-title' => $ms_page->post_title,  
  748. 'menu-item-url' => $page_url,  
  749. 'menu-item-status' => 'publish',  
  750. ); 
  751.  
  752. $item = ! is_array( $items ) ? false : array_shift( $items ); 
  753. $db_id = empty( $item ) ? 0 : $item->db_id; 
  754.  
  755. if ( $db_id || ! $update_only ) { 
  756. wp_update_nav_menu_item( $nav->term_id, $db_id, $menu_item ); 
  757. self::set_setting( 'has_nav_' . $page_type, true ); 
  758. $res = true; 
  759. } else { 
  760. // No menus defined. 
  761. $res = true; 
  762.  
  763. return $res; 
  764.  
  765. /** 
  766. * Remove MS Pages from Menus. 
  767. * 
  768. * @since 1.1.0 
  769. * 
  770. * @param string $page_type The page type to create menu. 
  771. * @return bool True means that at least one menu item was deleted. 
  772. */ 
  773. static public function drop_menu( $page_type ) { 
  774. $res = false; 
  775.  
  776. if ( self::is_valid_type( $page_type ) ) { 
  777. $ms_page = self::get_page( $page_type, true ); 
  778. $navs = wp_get_nav_menus( array( 'orderby' => 'name' ) ); 
  779.  
  780. if ( ! empty( $navs ) ) { 
  781. foreach ( $navs as $nav ) { 
  782. $args['meta_query'] = array( 
  783. array( 
  784. 'key' => '_menu_item_object_id',  
  785. 'value' => $ms_page->ID,  
  786. ),  
  787. array( 
  788. 'key' => '_menu_item_object',  
  789. 'value' => 'page',  
  790. ),  
  791. array( 
  792. 'key' => '_menu_item_type',  
  793. 'value' => 'post_type',  
  794. ),  
  795. ); 
  796.  
  797. // Search for existing menu item and create it if not found 
  798. $items = wp_get_nav_menu_items( $nav, $args ); 
  799.  
  800. $item = ! is_array( $items ) ? false : array_shift( $items ); 
  801. $db_id = empty( $item ) ? 0 : $item->db_id; 
  802.  
  803. if ( $db_id ) { 
  804. if ( false !== wp_delete_post( $db_id ) ) { 
  805. self::set_setting( 'has_nav_' . $page_type, false ); 
  806. $res = true; 
  807. } else { 
  808. // No menus defined. 
  809. $res = true; 
  810.  
  811. return $res; 
  812.  
  813. /** 
  814. * Returns the current menu state: If a specific page is added to the menu,  
  815. * this state is saved in the settings. So when the user removes a menu item 
  816. * manually we still have the "inserted" flag in DB. 
  817. * 
  818. * We do this, because the menu items are added to all existing nav menus 
  819. * and the user might remove them from one nav menu but not from all... 
  820. * 
  821. * @since 1.1.0 
  822. * @param string $page_type 
  823. * @return bool 
  824. */ 
  825. static public function has_menu( $page_type ) { 
  826. $state = false; 
  827.  
  828. if ( ! MS_Plugin::is_network_wide() ) { 
  829. if ( self::is_valid_type( $page_type ) ) { 
  830. $state = self::get_setting( 'has_nav_' . $page_type ); 
  831. $state = lib2()->is_true( $state ); 
  832.  
  833. return $state; 
  834.  
  835.  
  836. /** 
  837. * Get default content for membership pages. 
  838. * 
  839. * @since 1.1.0 
  840. * 
  841. * @param string $type The page type name. 
  842. * @return string The default content. 
  843. */ 
  844. static public function get_default_content( $type ) { 
  845. $lines = array(); 
  846.  
  847. switch ( $type ) { 
  848. case self::MS_PAGE_MEMBERSHIPS: 
  849. $lines[] = sprintf( 
  850. '['. MS_Helper_Shortcode::SCODE_NOTE .' type="info"]%1$s[/'. MS_Helper_Shortcode::SCODE_NOTE .']',  
  851. __( 'We have the following subscriptions available for our site. You can renew, cancel or upgrade your subscriptions by using the forms below.', MS_TEXT_DOMAIN ) 
  852. ); 
  853. $lines[] = '['. MS_Helper_Shortcode::SCODE_SIGNUP .']'; 
  854. break; 
  855.  
  856. case self::MS_PAGE_PROTECTED_CONTENT: 
  857. $lines[] = '[' . MS_Helper_Shortcode::SCODE_PROTECTED . ']'; 
  858. break; 
  859.  
  860. case self::MS_PAGE_ACCOUNT: 
  861. $lines[] = '['. MS_Helper_Shortcode::SCODE_MS_ACCOUNT .']<hr />'; 
  862. $lines[] = '['. MS_Helper_Shortcode::SCODE_LOGOUT .']'; 
  863. break; 
  864.  
  865. case self::MS_PAGE_REGISTER: 
  866. $lines[] = sprintf( 
  867. '['. MS_Helper_Shortcode::SCODE_NOTE .' type="info"]%1$s[/'. MS_Helper_Shortcode::SCODE_NOTE .']',  
  868. __( 'We have the following subscriptions available for our site. To join, simply click on the Sign Up button and then complete the registration details.', MS_TEXT_DOMAIN ) 
  869. ); 
  870. $lines[] = '['. MS_Helper_Shortcode::SCODE_SIGNUP .']'; 
  871. break; 
  872.  
  873. case self::MS_PAGE_REG_COMPLETE: 
  874. $lines[] = sprintf( 
  875. '['. MS_Helper_Shortcode::SCODE_NOTE .' type="info"]%1$s<br/>%2$s[/'. MS_Helper_Shortcode::SCODE_NOTE .']',  
  876. __( 'Your request to join the membership was successfully received!', MS_TEXT_DOMAIN ),  
  877. __( 'The Payment Gateway could take a couple of minutes to process and return the payment status.', MS_TEXT_DOMAIN ) 
  878. ); 
  879. $lines[] = '['. MS_Helper_Shortcode::SCODE_MS_ACCOUNT_LINK .']'; 
  880. break; 
  881.  
  882. $content = implode( "\n", $lines ); 
  883.  
  884. return apply_filters( 
  885. 'ms_model_pages_get_default_content',  
  886. $content 
  887. ); 
  888.  
  889. /** 
  890. * Creates a new WordPress menu and adds all top level pages to this menu. 
  891. * 
  892. * @since 1.1.0 
  893. */ 
  894. static public function create_default_menu() { 
  895. $menu_id = wp_create_nav_menu( __( 'Default Menu', MS_TEXT_DOMAIN ) ); 
  896.  
  897. if ( ! is_numeric( $menu_id ) || $menu_id <= 0 ) { 
  898. return; 
  899.  
  900. // Use the new menu in the menu-location of the theme. 
  901. $locations = get_theme_mod( 'nav_menu_locations' ); 
  902. if ( is_array( $locations ) && count( $locations ) > 0 ) { 
  903. reset( $locations ); 
  904. $first = key( $locations ); 
  905. $locations[$first] = $menu_id; 
  906. set_theme_mod( 'nav_menu_locations', $locations ); 
  907.  
  908. // Enable the Auto-Add-New-Pages option. 
  909. // Code snippet from wp-admin/includes/nav-menu.php 
  910. $nav_menu_option = (array) get_option( 'nav_menu_options' ); 
  911. if ( ! isset( $nav_menu_option['auto_add'] ) ) { 
  912. $nav_menu_option['auto_add'] = array(); 
  913. if ( ! in_array( $menu_id, $nav_menu_option['auto_add'] ) ) { 
  914. $nav_menu_option['auto_add'][] = $menu_id; 
  915. update_option( 'nav_menu_options', $nav_menu_option ); 
  916.  
  917. // Get a list of all published top-level pages. 
  918. $top_pages = get_pages( 
  919. array( 'parent' => 0 ) 
  920. ); 
  921.  
  922. // List of pages that should not be displayed in the menu. 
  923. $skip_pages = array( 
  924. self::MS_PAGE_PROTECTED_CONTENT,  
  925. self::MS_PAGE_REG_COMPLETE,  
  926. ); 
  927.  
  928. foreach ( $top_pages as $page ) { 
  929. // Skip pages that should not appear in menu. 
  930. $ms_type = self::is_membership_page( $page->ID ); 
  931. if ( in_array( $ms_type, $skip_pages ) ) { 
  932. continue; 
  933.  
  934. // Add the page to our new menu! 
  935. $item = array( 
  936. 'menu-item-object-id' => $page->ID,  
  937. 'menu-item-object' => $page->post_type,  
  938. 'menu-item-type' => 'post_type',  
  939. 'menu-item-status' => $page->post_status,  
  940. ); 
  941. wp_update_nav_menu_item( $menu_id, 0, $item ); 
  942.  
.