PluginProbe
MLSImport: IDX Plugin & MLS Plugin for Real Estate Listings / 7.1.2
MLSImport: IDX Plugin & MLS Plugin for Real Estate Listings v7.1.2
7.2.1 7.2 7.1.2 7.1.1 7.1 7.0.4 7.0.6 7.0.7 6.3.8 6.3.7 6.3.6 6.3.5 6.3.4 6.3.3 6.3.1 trunk 5.7.3 5.7.5 5.8.1 5.8.2 5.8.3 5.8.4 5.8.6 6.0.4 6.0.5 All 36 releases
mlsimport / includes / class-mlsimport-item.php

class-mlsimport-item.php in MLSImport: IDX Plugin & MLS Plugin for Real Estate Listings 7.1.2, at includes/class-mlsimport-item.php

326 lines 13.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // Guard: block direct web access — only load when WordPress is bootstrapped.
3 if ( ! defined( 'ABSPATH' ) ) {
4 exit; // Exit if accessed directly
5 }
6
7
8 /*
9 * To change this license header, choose License Headers in Project Properties.
10 * To change this template file, choose Tools | Templates
11 * and open the template in the editor.
12 */
13
14
15 /**
16 * Registers the plugin's custom post type(s).
17 *
18 * File role: defines the `mlsimport_item` ("Import Tasks") custom post type — each post is
19 * one import task configuration processed by the cron/import pipeline. create_custom_post_type()
20 * builds the CPT arguments and delegates to register_single_post_type(), which calls
21 * register_post_type(); optional custom capabilities are wired through assign_capabilities().
22 *
23 * @author cretu
24 */
25 class Mlsimport_Item {
26
27
28 // put your code here
29
30
31 /**
32 * Constructor — no initialization required.
33 */
34 public function __construct() {
35 }
36
37 /**
38 * Build the arguments for and register a single custom post type.
39 *
40 * Assembles the labels and args arrays from a $fields definition, optionally applies a
41 * custom rewrite rule and a fine-grained capability map, registers the post type, then
42 * detaches the default category/post_tag taxonomies from mlsimport_item.
43 *
44 * @param array $fields Post-type definition (slug, singular/plural labels, args, flags).
45 * @return void
46 */
47 private function register_single_post_type( $fields ) {
48
49 // Human-readable admin labels, derived from the singular/plural names in $fields.
50 $labels = array(
51 'name' => $fields['plural'],
52 'singular_name' => $fields['singular'],
53 'menu_name' => $fields['menu_name'],
54 'new_item' => sprintf( __( 'New %s', 'mlsimport' ), $fields['singular'] ),
55 'add_new_item' => sprintf( __( 'Add new %s', 'mlsimport' ), $fields['singular'] ),
56 'edit_item' => sprintf( __( 'Edit %s', 'mlsimport' ), $fields['singular'] ),
57 'view_item' => sprintf( __( 'View %s', 'mlsimport' ), $fields['singular'] ),
58 'view_items' => sprintf( __( 'View %s', 'mlsimport' ), $fields['plural'] ),
59 'search_items' => sprintf( __( 'Search %s', 'mlsimport' ), $fields['plural'] ),
60 'not_found' => sprintf( __( 'No %s found', 'mlsimport' ), strtolower( $fields['plural'] ) ),
61 'not_found_in_trash' => sprintf( __( 'No %s found in trash', 'mlsimport' ), strtolower( $fields['plural'] ) ),
62 'all_items' => sprintf( __( 'All %s', 'mlsimport' ), $fields['plural'] ),
63 'archives' => sprintf( __( '%s Archives', 'mlsimport' ), $fields['singular'] ),
64 'attributes' => sprintf( __( '%s Attributes', 'mlsimport' ), $fields['singular'] ),
65 'insert_into_item' => sprintf( __( 'Insert into %s', 'mlsimport' ), strtolower( $fields['singular'] ) ),
66 'uploaded_to_this_item' => sprintf( __( 'Uploaded to this %s', 'mlsimport' ), strtolower( $fields['singular'] ) ),
67
68 /* Labels for hierarchical post types only. */
69 'parent_item' => sprintf( __( 'Parent %s', 'mlsimport' ), $fields['singular'] ),
70 'parent_item_colon' => sprintf( __( 'Parent %s:', 'mlsimport' ), $fields['singular'] ),
71
72 /* Custom archive label. Must filter 'post_type_archive_title' to use. */
73 'archive_title' => $fields['plural'],
74 );
75
76 // register_post_type() arguments; each flag falls back to a sensible default when unset in $fields.
77 $args = array(
78 'labels' => $labels,
79 'description' => ( isset( $fields['description'] ) ) ? $fields['description'] : '',
80 'public' => ( isset( $fields['public'] ) ) ? $fields['public'] : true,
81 'publicly_queryable' => ( isset( $fields['publicly_queryable'] ) ) ? $fields['publicly_queryable'] : true,
82 'exclude_from_search' => ( isset( $fields['exclude_from_search'] ) ) ? $fields['exclude_from_search'] : false,
83 'show_ui' => ( isset( $fields['show_ui'] ) ) ? $fields['show_ui'] : true,
84 'show_in_menu' => ( isset( $fields['show_in_menu'] ) ) ? $fields['show_in_menu'] : true,
85 'query_var' => ( isset( $fields['query_var'] ) ) ? $fields['query_var'] : true,
86 'show_in_admin_bar' => ( isset( $fields['show_in_admin_bar'] ) ) ? $fields['show_in_admin_bar'] : true,
87 'capability_type' => ( isset( $fields['capability_type'] ) ) ? $fields['capability_type'] : 'post',
88 'map_meta_cap' => ! empty( $fields['map_meta_cap'] ),
89 'has_archive' => ( isset( $fields['has_archive'] ) ) ? $fields['has_archive'] : true,
90 'hierarchical' => ( isset( $fields['hierarchical'] ) ) ? $fields['hierarchical'] : true,
91 'supports' => ( isset( $fields['supports'] ) ) ? $fields['supports'] : array(
92 'title',
93 'editor',
94 'excerpt',
95 'author',
96 'thumbnail',
97 'comments',
98 'trackbacks',
99 'custom-fields',
100 'revisions',
101 'page-attributes',
102 'post-formats',
103 ),
104 'menu_position' => ( isset( $fields['menu_position'] ) ) ? $fields['menu_position'] : 21,
105 'menu_icon' => ( isset( $fields['menu_icon'] ) ) ? $fields['menu_icon'] : 'dashicons-admin-generic',
106 'show_in_nav_menus' => ( isset( $fields['show_in_nav_menus'] ) ) ? $fields['show_in_nav_menus'] : true,
107 'taxonomies' => array( 'category', 'post_tag' ),
108 );
109
110 // Apply a custom permalink rewrite rule when the definition supplies one.
111 if ( isset( $fields['rewrite'] ) ) {
112
113 /**
114 * Add $this->plugin_name as translatable in the permalink structure,
115 * to avoid conflicts with other plugins which may use customers as well.
116 */
117 $args['rewrite'] = $fields['rewrite'];
118 }
119
120 // When custom capabilities are requested, replace the default cap set with a granular map.
121 if ( $fields['custom_caps'] ) {
122
123 /**
124 * Provides more precise control over the capabilities than the defaults. By default, WordPress
125 * will use the 'capability_type' argument to build these capabilities. More often than not,
126 * this results in many extra capabilities that you probably don't need. The following is how
127 * I set up capabilities for many post types, which only uses three basic capabilities you need
128 * to assign to roles: 'manage_examples', 'edit_examples', 'create_examples'. Each post type
129 * is unique though, so you'll want to adjust it to fit your needs.
130 *
131 * @link https://gist.github.com/creativembers/6577149
132 * @link http://justintadlock.com/archives/2010/07/10/meta-capabilities-for-custom-post-types
133 */
134 $args['capabilities'] = array(
135
136 // Meta capabilities
137 'edit_post' => 'edit_' . strtolower( $fields['singular'] ),
138 'read_post' => 'read_' . strtolower( $fields['singular'] ),
139 'delete_post' => 'delete_' . strtolower( $fields['singular'] ),
140
141 // Primitive capabilities used outside of map_meta_cap():
142 'edit_posts' => 'edit_' . strtolower( $fields['plural'] ),
143 'edit_others_posts' => 'edit_others_' . strtolower( $fields['plural'] ),
144 'publish_posts' => 'publish_' . strtolower( $fields['plural'] ),
145 'read_private_posts' => 'read_private_' . strtolower( $fields['plural'] ),
146
147 // Primitive capabilities used within map_meta_cap():
148 'delete_posts' => 'delete_' . strtolower( $fields['plural'] ),
149 'delete_private_posts' => 'delete_private_' . strtolower( $fields['plural'] ),
150 'delete_published_posts' => 'delete_published_' . strtolower( $fields['plural'] ),
151 'delete_others_posts' => 'delete_others_' . strtolower( $fields['plural'] ),
152 'edit_private_posts' => 'edit_private_' . strtolower( $fields['plural'] ),
153 'edit_published_posts' => 'edit_published_' . strtolower( $fields['plural'] ),
154 'create_posts' => 'edit_' . strtolower( $fields['plural'] ),
155
156 );
157
158 /**
159 * Adding map_meta_cap will map the meta correctly.
160 *
161 * @link https://wordpress.stackexchange.com/questions/108338/capabilities-and-custom-post-types/108375#108375
162 */
163 $args['map_meta_cap'] = true;
164
165 /**
166 * Assign capabilities to users
167 * Without this, users - also admins - can not see post type.
168 */
169 $this->assign_capabilities( $args['capabilities'], $fields['custom_caps_users'] );
170 }
171
172 // Register the post type with WordPress using the assembled slug and args.
173 register_post_type( $fields['slug'], $args );
174
175 // Dedicated capability type: only administrators receive the caps.
176 if ( ! empty( $fields['map_meta_cap'] ) ) {
177 $this->grant_admin_capabilities( $fields['slug'] );
178 }
179
180 /**
181 * Register Taxnonmies if any
182 *
183 * @link https://codex.wordpress.org/Function_Reference/register_taxonomy
184 */
185 // Import tasks are not taxonomy-organized: detach the default tag and category taxonomies.
186 unregister_taxonomy_for_object_type( 'post_tag', 'mlsimport_item' );
187 unregister_taxonomy_for_object_type( 'category', 'mlsimport_item' );
188
189 }
190
191
192
193 /**
194 * Grant a post type's primitive capabilities to the administrator role.
195 *
196 * Import Tasks use a dedicated capability type so ordinary post
197 * capabilities (author/editor) never reach them; the caps therefore have
198 * to be granted explicitly, and only administrators get them. Meta caps
199 * (edit_post/read_post/delete_post) are skipped — map_meta_cap resolves
200 * those to the primitives at check time. Idempotent: roles are only
201 * written when a capability is actually missing.
202 *
203 * @param string $slug Registered post type slug.
204 * @return void
205 */
206 private function grant_admin_capabilities( $slug ) {
207 $role = get_role( 'administrator' );
208 $post_type = get_post_type_object( $slug );
209 if ( ! $role || ! $post_type ) {
210 return;
211 }
212
213 $meta_caps = array( 'edit_post', 'read_post', 'delete_post' );
214 foreach ( (array) $post_type->cap as $core_cap => $capability ) {
215 if ( in_array( $core_cap, $meta_caps, true ) || 'read' === $capability ) {
216 continue;
217 }
218 if ( ! $role->has_cap( $capability ) ) {
219 $role->add_cap( $capability );
220 }
221 }
222 }
223
224 /**
225 * Assign capabilities to users
226 *
227 * Grants every capability in the map to each named role so those roles can see and manage
228 * the custom post type (without this even administrators cannot access it).
229 *
230 * @link https://codex.wordpress.org/Function_Reference/register_post_type
231 * @link https://typerocket.com/ultimate-guide-to-custom-post-types-in-wordpress/
232 *
233 * @param array $caps_map Map of WordPress cap key => custom capability string.
234 * @param array $users Role slugs (e.g. 'administrator') to receive the capabilities.
235 * @return void
236 */
237 public function assign_capabilities( $caps_map, $users ) {
238
239 // Loop over each target role slug.
240 foreach ( $users as $user ) {
241 $user_role = get_role( $user );
242
243 // Add every mapped capability to that role.
244 foreach ( $caps_map as $cap_map_key => $capability ) {
245 $user_role->add_cap( $capability );
246 }
247 }
248 }
249
250
251
252
253 /**
254 * Create post types.
255 *
256 * Defines the mlsimport_item ("Import Tasks") post type configuration and registers it.
257 * Typically hooked to 'init'. Built as an array of definitions so more CPTs can be added
258 * to the loop later.
259 *
260 * @return void
261 */
262 public function create_custom_post_type() {
263
264 /**
265 * This is not all the fields, only what I find important. Feel free to change this function ;)
266 *
267 * @link https://codex.wordpress.org/Function_Reference/register_post_type
268 *
269 * For more info on fields:
270 * @link https://github.com/JoeSz/WordPress-Plugin-Boilerplate-Tutorial/blob/9fb56794bc1f8aebfe04e99b15881db0c4bc61bd/mlsimport/includes/class-mlsimport-post_types.php#L230
271 */
272
273 // Base slug used in the permalink rewrite structure below.
274 $custom_slug = 'mlsimport';
275
276 // One definition per custom post type; currently just the mlsimport_item task type.
277 $post_types_fields = array(
278 array(
279 'slug' => 'mlsimport_item',
280 'singular' => __( 'Import Task', 'mlsimport' ),
281 'plural' => __( 'Import Tasks', 'mlsimport' ),
282 'menu_name' => __( 'Import Tasks', 'mlsimport' ),
283 'description' => __( 'Import Task', 'mlsimport' ),
284 'has_archive' => true,
285 'hierarchical' => false,
286 'menu_icon' => 'dashicons-tag',
287 'rewrite' => array(
288 'slug' => $custom_slug,
289 'with_front' => true,
290 'pages' => true,
291 'feeds' => true,
292 'ep_mask' => EP_PERMALINK,
293 ),
294 'menu_position' => 21,
295 'public' => false,
296 'publicly_queryable' => false,
297 'exclude_from_search' => true,
298 'show_ui' => true,
299 'show_in_menu' => true,
300 'query_var' => true,
301 'show_in_admin_bar' => true,
302 'show_in_nav_menus' => false,
303 // Admin-only boundary: dedicated caps, granted solely to administrators.
304 'capability_type' => array( 'mlsimport_item', 'mlsimport_items' ),
305 'map_meta_cap' => true,
306 'supports' => array(
307 'title',
308
309 ),
310 'custom_caps' => false,
311 'custom_caps_users' => array(
312 'administrator',
313 ),
314 'taxonomies' => array(),
315 'menu_icon' => MLSIMPORT_PLUGIN_URL . '/img/mlsimport_menu.png',
316 ),
317 );
318
319 // loop torugh custom post type array and register
320 // Register each defined post type in turn.
321 foreach ( $post_types_fields as $fields ) {
322 $this->register_single_post_type( $fields );
323 }
324 }
325 }
326