├── README.md
├── authentication-filters.MD
├── classes
└── Pods
│ └── JSON
│ └── API
│ ├── Init.php
│ ├── Pods.php
│ └── Pods
│ ├── API.php
│ └── Components.php
├── composer.json
├── pods-json-api.php
└── readme.txt
/README.md:
--------------------------------------------------------------------------------
1 | Pods JSON API
2 | ===========
3 | DEPRECATION NOTICE This plugin is deprecated. It should continue to work with version 1 of the REST API, but is no longer supported. Pods 2.6 and later has support for the WordPress REST API version 2 included.
4 |
5 | This is a plugin that implements the `pods` and `pods-api` routes for [WP-API](https://github.com/WP-API/WP-API) Version 1.
6 |
7 | It provides access to various methods in the Pods and Pods API classes in the [Pods Framework](http://pods.io).
8 |
9 | [Slides from PodsCamp DFW 2014 presentation: "Introduction To The Pods JSON API"](http://www.slideshare.net/podsframework/introduction-to-the-pods-json-api)
10 |
11 | ### Requirements
12 |
13 | * [WP-API](https://github.com/WP-API/WP-API) 1.0 or newer
14 | * [PHP](http://php.net/) 5.3 or newer
15 | * [WordPress](http://wordpress.org/) 3.9 or newer
16 | * [Pods Framework](http://Pods.io)
17 |
18 | ### Resources
19 | * [Authentication Filters For The Pods JSON API](https://github.com/pods-framework/pods-json-api/blob/master/authentication-filters.MD)
20 | * [WP-API Getting Started Guide](https://github.com/WP-API/WP-API/blob/master/docs/guides/getting-started.md)
21 | * [WP-API Docs](https://github.com/WP-API/WP-API/blob/master/docs/)
22 | * [WP-API Console](https://github.com/WP-API/api-console)
23 | * [oAuth Authentication](https://github.com/WP-API/OAuth1) Recomended For Production
24 | * [Basic Authentication](https://github.com/WP-API/Basic-Auth) Recommended For Testing & Debugging
25 |
26 | ### Endpoints
27 |
28 | #### Pods Data
29 |
30 | `/pods/`
31 |
32 | * `get_items` (READABLE | ACCEPT_JSON)
33 | * Get items from a Pod using find()
34 | * Uses JSON object as an array of find() $params
35 | * Returns an array of objects of data
36 | * `add_item` (CREATABLE | ACCEPT_JSON)
37 | * Add an item to a Pod
38 | * Uses JSON object as an array of data to save
39 | * Success sends you to `get_item` URL
40 |
41 | `/pods//- `
42 |
43 | * `get_item` (READABLE)
44 | * Get an item from a Pod
45 | * Returns object of data
46 | * `save_item` (EDITABLE | ACCEPT_JSON)
47 | * Save an item from a Pod
48 | * Uses JSON object as an array of data to save
49 | * Success sends you to `get_item` URL
50 | * `delete_item` (DELETABLE)
51 | * Delete an item from a Pod
52 |
53 | `/pods//
- /duplicate`
54 |
55 | * `duplicate_item` (CREATABLE | ACCEPT_JSON)
56 | * Duplicate an item from a Pod
57 | * Uses JSON object as an array of data to override save on the new item
58 | * Success sends you to `get_item` URL
59 |
60 | #### Pods API
61 |
62 | `/pods-api`
63 |
64 | * `get_pods` (READABLE)
65 | * Get Pods registered, excluding fields
66 | * Returns an array of objects of data
67 | * `add_pod` (CREATABLE | ACCEPT_JSON)
68 | * Add a Pod
69 | * Uses JSON object as an array of data to save
70 |
71 | `/pods-api/`
72 |
73 | * `get_pod` (READABLE)
74 | * Get a Pod, including fields
75 | * Returns object of data
76 | * `save_pod` (EDITABLE | ACCEPT_JSON)
77 | * Save a Pod
78 | * Uses JSON object as an array of data to save
79 | * Success sends you to `get_pod` URL
80 | * `delete_pod` (DELETABLE)
81 | * Delete a Pod
82 |
83 | `/pods-api//duplicate`
84 |
85 | * `duplicate_pod` (CREATABLE | ACCEPT_JSON)
86 | * Duplicate a Pod
87 | * Uses JSON object as an array of data to override save on the new Pod
88 | * Success sends you to `get_pod` URL
89 | * `reset_pod` (DELETABLE)
90 | * Reset a Pod's contents
91 |
92 | `/pods-api//update_rel`
93 |
94 | * `update_rel` (EDITABLE | ACCEPT_JSON)
95 | * Update bi-directional relationships to correct sister IDs.
96 | * Uses JSON object as an array of data to set relationships. Must be in form documented below.
97 | * Success returns to a list of field IDs that were updated.
98 |
99 | #### Pods Components
100 | `/pods-components?package`
101 |
102 | * `package` (CREATABLE | ACCEPT_JSON)
103 | * Import a Pods Package
104 | * Requires that the Pods Migrate Package component be active on remote site.
105 | * Success returns true. Failure false.
106 |
107 |
108 | `/pods-components?activate_components`
109 |
110 | * `activate_components` (EDITABLE | ACCEPT_JSON)
111 | * Bulk activates and/ or deactivates components.
112 | * Takes a multi-dimensional array containing a 'activate' and or 'deactivate' key, each of which should contain an array of Pods Component names.
113 | * Use PUT request.
114 | * Success returns true. Failure false.
115 |
116 | `/pods-components/activate/`
117 |
118 | *`activate` (EDITABLE)
119 | * Activate a single component
120 | * Use POST request.
121 | * Success returns true. Failure false.
122 |
123 | `/pods-components/activate/`
124 |
125 | *`deactivate` (DELETABLE)
126 | * Deactivate a single component
127 | * Use DELETE request.
128 | * Success returns true. Failure false.
129 |
130 | ### Using AJAX
131 | * Example code is being migrated to our code-library repository.
132 |
133 | See https://github.com/pods-framework/pods-code-library/tree/master/example/misc/json-api/examples for examples using AJAX.
134 |
135 | ### Passing Parameters To Methods
136 | You can pass the same parameters to each method as you usually would in the methods `$parameters` array, when using the method via PHP, by appending variables to the URL.
137 |
138 | ##### Querying For Pods Items With GET Requests
139 |
140 | For example, to do a `Pods::find()` query on the Pod 'soup' that was the equivalent of:
141 |
142 | ```php
143 | $params = array(
144 | 'where' => 't.is_spicy = 1',
145 | 'limit' => '7',
146 | );
147 | $pods = pods( 'soup', $params );
148 | ```
149 |
150 | You would use the url encoded equivalent of `soup/find?where=t.is_spicy%3D1&limit=7` by passing the values through `urlencode()`.
151 |
152 | You can convert a PHP array, designed to be passed to `Pods::find()` or another method, to an encoded string, by first passing it through a foreach loop and encoding the values. For example, to create a long query, without manually encoding URLs, you could do:
153 |
154 | ```php
155 | $params = array(
156 | 'where' => 'serves.meta_value = "four or more"',
157 | 'limit' => '7',
158 | 'orderby' => 't.post_title ASC'
159 | );
160 |
161 | $url = json_url( 'pods/soup?find=' );
162 |
163 | $url = http_build_query( $params );
164 | ```
165 | The variable, `$url` now has the url to query the 'soup' Pod, using `Pods::find()` by the parameters set in the array.
166 |
167 | In the above example, the method find is used to illustrate the point that all methods of the Pods and Pods_API class that are accessible via this plugin can be specified this way. It is not actually needed as find is the default method for GET requests, while add is the default method for PUT requests.
168 |
169 | All that is actually needed to create a find request is:
170 |
171 | ```php
172 | $params = array(
173 | 'where' => 'serves.meta_value = "four or more"',
174 | 'limit' => '7',
175 | 'orderby' => 't.post_title ASC'
176 | );
177 |
178 | $url = json_url( 'pods/soup' );
179 |
180 | $url = add_query_arg( $params, $url );
181 | ```
182 |
183 | ##### Updating Items With Post Requests
184 | By default POST requests, sent to a Pods class endpoint will default to save_item. This allows for creating new items or updating existing items. In this example, a custom field--"home planet"--in anexisting item--Pod name "jedi", post ID 9--is being updated:
185 |
186 | ```php
187 | $data = array( 'home_planet' => 'Alderann' );
188 | $url = json_url( 'pods/jedi/9' );
189 |
190 | //This example uses the basic authentication plugin for authentication
191 | $headers = array (
192 | 'Authorization' => 'Basic ' . base64_encode( 'username' . ':' . 'password' ),
193 | );
194 |
195 | $response = wp_remote_post( $url, array (
196 | 'method' => 'POST',
197 | 'headers' => $headers,
198 | 'body' => json_encode( $data )
199 | )
200 | );
201 |
202 | //make sure response isn't an error
203 | if ( ! is_wp_error( $response ) ) {
204 |
205 | //show the updated post item
206 | var_dump( wp_remote_retrieve_body( $response ) );
207 | }
208 | ```
209 |
210 | ### Using The `update_rel` Endpoint
211 | *Added in version 0.2
212 |
213 | This endpoint is designed to address an issue that can occur when using the `add_pod` or `save_pod` methods with bi-directional relationship fields.
214 |
215 | When these types of fields are updated/ created via the API, at the time of field creation/edit the sister IDs--the ID of the field in related Pod--can not be set if the related field does not yet exist and therefore does not have an ID. In addition, if the configuration is being copied from a remote site, the field IDs will be diffrent.
216 |
217 | This endpoint is designed to be used to correct these errors after all Pods and Pods Fields are created. The data passed to it should be a multi-dimensional array, with each field represented like this:
218 |
219 | ```
220 | [pod_name_field_name] =>
221 | [from] =>
222 | [field_name] => 'field_name',
223 | [pod_name] => 'pod_name',
224 | [to] =>
225 | [field_name] => 'field_name',
226 | [pod_name] => 'pod_name',
227 | ```
228 |
229 | ### Importing a Pods Migrate Package
230 | *Added in version 0.2
231 |
232 | The pods-components endpoint allows for running a Pods Package import via the API. It can be used to import Pods, Pods Templates, Pods Pages and Pods Helpers. It requires that the Pods Migrate Package component be active on the remote site.
233 |
234 | You can pass the Pods Package data--which is already in JSON format--to the body of a POST request.
235 |
236 |
237 | ### Activating & Deactivating Components
238 | *Added in version 0.2
239 | You may bulk activate and/ or deactivate components with a PUT request to the pods-packages endpoint. You may also activate and/ or deactivate components individually using the `pods-components/activate/` endpoint, using a POST request to activate, or a DELETE request to deactivate.
240 |
241 | The activate/deactivate methods return true, with a status of 201 if the option that stores active components was updated and false, with a status of 500, if it was not. You can get a list of all components and their activation status by making a GET request to the pods-component endpoint.
242 |
243 | Get a list of all components and whether they are active or not:
244 | ```
245 | $url = json_url( 'pods-components' );
246 |
247 | //This example uses the basic authentication plugin for authentication
248 | $headers = array (
249 | 'Authorization' => 'Basic ' . base64_encode( 'admin' . ':' . 'password' ),
250 | );
251 |
252 | $response = wp_remote_post( $url, array (
253 | 'method' => 'GET',
254 | 'headers' => $headers,
255 | )
256 | );
257 | ```
258 |
259 | Activate and/ or deactivate multiple components at once:
260 | ```
261 | $data = array( 'deactivate' => array( 'templates', 'table-storage' ), 'activate' => array( 'pages' ) );
262 |
263 | $url = json_url( 'pods-components?activate_components' );
264 |
265 | //This example uses the basic authentication plugin for authentication
266 | $headers = array (
267 | 'Authorization' => 'Basic ' . base64_encode( 'admin' . ':' . 'password' ),
268 | );
269 |
270 |
271 | $response = wp_remote_post( $url, array (
272 | 'method' => 'PUT',
273 | 'headers' => $headers,
274 | 'body' => json_encode( $data )
275 | )
276 | );
277 | ```
278 | Activate one component:
279 |
280 | ```
281 | $url = json_url( 'pods-components/activate/table-storage' );
282 |
283 | //This example uses the basic authentication plugin for authentication
284 | $headers = array (
285 | 'Authorization' => 'Basic ' . base64_encode( 'admin' . ':' . 'password' ),
286 | );
287 |
288 | $response = wp_remote_post( $url, array (
289 | 'method' => 'POST',
290 | 'headers' => $headers,
291 | )
292 | );
293 | ```
294 |
295 | Deactivate one component:
296 |
297 | ```
298 | $url = json_url( 'pods-components/activate/templates' );
299 |
300 | //This example uses the basic authentication plugin for authentication
301 | $headers = array (
302 | 'Authorization' => 'Basic ' . base64_encode( 'admin' . ':' . 'password' ),
303 | );
304 |
305 | $response = wp_remote_post( $url, array (
306 | 'method' => 'DELETE',
307 | 'headers' => $headers,
308 | )
309 | );
310 | ```
311 |
--------------------------------------------------------------------------------
/authentication-filters.MD:
--------------------------------------------------------------------------------
1 | # Pods JSON API Access Filters
2 |
3 | ### Introduction
4 | By default, all Pods-JSON-API endpoints and routes require authentication. In the `/pods/` route, access is granted automatically if the current user has the correct capabilities for the current route. For example, making a POST request to the `/pods//` route to add an item requires authenticating as a user with the "pods_add_" capability. Currently, [this only applies to Advanced Content Type Pods](https://github.com/pods-framework/pods-json-api/issues/14).
5 |
6 | Once a user connecting via the REST API is authenticated by one of the systems provided by [the core REST API project](https://github.com/rest-api) you can use the same permissions checks as you would in any other WordPress plugin. Because of this, you can You can grant access by route or by endpoint. You can also use your own authentication system to conditionally grant access to the routes or endpoints required for your use case.
7 |
8 | There are two main strategies for implementing these filters:
9 |
10 | 1) Based on current user's capabilities:
11 | Check a current logged in user's capabilities, IE `if ( current_user_can( 'edit_posts' ) )`, and grant access conditionally.
12 |
13 | 2) Globally.
14 | Grant or deny access to all users for specific endpoints/routes.
15 |
16 | ### The Basic Pattern
17 | In the Pods JSON API uses a pattern of one global filter per route and one dynamically created filter for each endpoint. All of these filters return a boolean, called `$access`. If true, access is granted, if false, access is denied.
18 |
19 | The Pods route has a filter that applies to all endpoints in that route "pods_json_api_access_pods". The pods-api route has a similar filter "pods_json_api_access_pods_api" and the components route has the "pods_json_api_access_components" filter. So, for example, to lock out all users, authenticated or not from the pods-api route, you can use:
20 |
21 | ```php
22 | add_filter( 'pods_json_api_access_pods_api', '__return_false' );
23 | ```
24 |
25 | The filters mentioned above apply to all endpoints of the route. There is also one filter dynamically generated using the name of the method that is used to process the endpoint. For example, when making a GET request to the `pods/` endpoint, the method "get_items" is used. Therefore you can grant global access to this endpoint, for all Pods, like this:
26 |
27 | ```php
28 | add_filter( 'pods_json_api_access_pods_get_items', '__return_true' );
29 | ```
30 |
31 | Because these filters have the Pod name as their second argument, you can also grant or deny access by Pod. For example, to deny access to a Pod called "jedi" but grant for all others, you would use the following:
32 |
33 | ```php
34 | add_filter( 'pods_json_api_access_pods_get_items', function( $access, $method, $pod ) {
35 | if ( 'jedi' == $pod ) {
36 | $access = false;
37 | }
38 | else {
39 | $access = true;
40 | }
41 |
42 | return $access;
43 | }, 10, 3 );
44 | ```
45 |
46 | ### Using Current User Permissions
47 | As noted in the introduction, once authenticated, the current user's capabilities can be checked, just like in any other context. For this reason, authentication alone does not categorically grant access to the routes added by this plugin. Also, when working with standard WordPress content types, such as post types and taxonomies, the default WordPress permissions can be used.
48 |
49 | For example, if you have a custom post type Pod, you may wish to grant global access to the Pods route, for all users who have the capability "edit_posts", like this:
50 |
51 | ```php
52 | add_filter( 'pods_json_api_access_pods', function( $access ) {
53 | if ( current_user_can( 'edit_posts' )) {
54 | $access = true;
55 | }
56 |
57 |
58 | return $access;
59 | } );
60 | ```
61 |
62 | In the Pods editor, for a custom post type Pod, you can enable the "user capabilities" option. This enables specific capabilities for the Pod. So, if your Pod was called "jedi", you could assign the "edit_jedi" capability to users. Then you can grant them
63 | ability to create and edit posts in the jedi post type via the API like this:
64 |
65 | ```php
66 | add_filter( 'pods_json_api_access_pods', function( $access, $method, $pod ) {
67 | if ( 'jedi' == $pod && in_array( $method, array( 'save_item', 'add_item' ) ) && current_user_can( 'edit_jedi' ) {
68 | $access = true;
69 | }
70 |
71 | return $access;
72 | } );
73 | ```
74 |
--------------------------------------------------------------------------------
/classes/Pods/JSON/API/Init.php:
--------------------------------------------------------------------------------
1 | [\w\-\_]+)' ] = array(
20 | array( array( $this, 'get_items' ), WP_JSON_Server::READABLE | WP_JSON_Server::ACCEPT_JSON ),
21 | array( array( $this, 'add_item' ), WP_JSON_Server::CREATABLE | WP_JSON_Server::ACCEPT_JSON )
22 | );
23 |
24 | $routes[ '/pods/(?P[\w\-\_]+)/(?P
- [\w\-\_]+)' ] = array(
25 | array( array( $this, 'get_item' ), WP_JSON_Server::READABLE ),
26 | array( array( $this, 'save_item' ), WP_JSON_Server::EDITABLE | WP_JSON_Server::ACCEPT_JSON ),
27 | array( array( $this, 'delete_item' ), WP_JSON_Server::DELETABLE )
28 | );
29 |
30 | $routes[ '/pods/(?P[\w\-\_]+)/(?P\d+)/duplicate' ] = array(
31 | array( array( $this, 'duplicate_item' ), WP_JSON_Server::CREATABLE | WP_JSON_Server::ACCEPT_JSON )
32 | );
33 |
34 | return $routes;
35 |
36 | }
37 |
38 | /**
39 | * List Pod items
40 | *
41 | * @param string $pod Pod name
42 | * @param array $data find() parameters
43 | *
44 | * @return array
45 | *
46 | * @access public
47 | */
48 | public function get_items( $pod, $data = array() ) {
49 |
50 | if ( !$this->check_access( __FUNCTION__, $pod ) ) {
51 | return new WP_Error( 'pods_json_api_restricted_error_' . __FUNCTION__, __( 'Sorry, you do not have access to this endpoint.', 'pods-json-api' ) );
52 | }
53 |
54 | try {
55 | $fields = null;
56 | $depth = 2;
57 |
58 | $find_params = pods_sanitize( $data );
59 |
60 | if ( ! empty( $find_params['export_fields'] ) ) {
61 | $fields = $find_params['export_fields'];
62 |
63 | if ( ! is_array( $fields ) ) {
64 | $fields = explode( ',', $fields );
65 | }
66 |
67 | unset( $find_params['export_fields'] );
68 | }
69 |
70 | if ( ! empty( $find_params['export_depth'] ) ) {
71 | $depth = (int) $find_params['export_depth'];
72 |
73 | unset( $find_params['export_depth'] );
74 | }
75 |
76 | // Force limited $find_params if not admin
77 | if ( ! $this->check_access( false ) ) {
78 | $safe_params = array();
79 |
80 | if ( isset( $find_params[ 'limit' ] ) ) {
81 | $safe_params[ 'limit' ] = (int) $find_params[ 'limit' ];
82 | }
83 |
84 | if ( isset( $find_params[ 'page' ] ) ) {
85 | $safe_params[ 'page' ] = (int) $find_params[ 'page' ];
86 | }
87 |
88 | if ( isset( $find_params[ 'offset' ] ) ) {
89 | $safe_params[ 'offset' ] = (int) $find_params[ 'offset' ];
90 | }
91 |
92 | $find_params = $safe_params;
93 | }
94 |
95 | $find_params = apply_filters( 'pods_json_api_pods_get_items_params', $find_params, $pod, $data );
96 |
97 | $params = array(
98 | 'fields' => $fields,
99 | 'depth' => $depth,
100 | 'params' => $find_params
101 | );
102 |
103 | $params = apply_filters( 'pods_json_api_pods_get_items_full_params', $params, $pod, $data );
104 |
105 | $items = pods_api()->export( $pod, $params );
106 |
107 | $items = apply_filters( 'pods_json_api_pods_get_items', $items, $pod, $params, $data );
108 |
109 | /**
110 | * Optionally do not return user email and password for user pod
111 | *
112 | * If false, user's email and their hashed password will not be returned.
113 | *
114 | * @since 0.2.1
115 | *
116 | * @param bool True to not return email/password
117 | */
118 | if ( $pod === 'user' && apply_filters( 'pods_json_api_disable_sensitive_user_data', true ) ) {
119 | if ( isset( $items[ 'user_email' ] ) ) {
120 | unset( $items[ 'user_email' ] );
121 | }
122 |
123 | if ( isset( $items[ 'user_pass' ] ) ) {
124 | unset( $items[ 'user_pass' ] );
125 | }
126 | }
127 | }
128 | catch ( Exception $e ) {
129 | $items = new WP_Error( $e->getCode(), $e->getMessage() );
130 | }
131 |
132 | return $items;
133 |
134 | }
135 |
136 | /**
137 | * Add a Pod item
138 | *
139 | * @param string $pod Pod name
140 | * @param array $data Pod item data
141 | *
142 | * @return boolean|WP_Error
143 | *
144 | * @access public
145 | */
146 | public function add_item( $pod, $data ) {
147 |
148 | if ( !$this->check_access( __FUNCTION__, $pod ) ) {
149 | return new WP_Error( 'pods_json_api_restricted_error_' . __FUNCTION__, __( 'Sorry, you do not have access to this endpoint.', 'pods-json-api' ) );
150 | }
151 |
152 | if ( isset( $data[ 'id' ] ) ) {
153 | unset( $data[ 'id' ] );
154 | }
155 |
156 | try {
157 | $id = pods( $pod )->save( $data );
158 | }
159 | catch ( Exception $e ) {
160 | $id = new WP_Error( $e->getCode(), $e->getMessage() );
161 | }
162 |
163 | if ( $id instanceof WP_Error || !function_exists( 'json_ensure_response' ) ) {
164 | return $id;
165 | }
166 | elseif ( 0 < $id ) {
167 | $response = json_ensure_response( $this->get_item( $pod, $id ) );
168 | $response->set_status( 201 );
169 | $response->header( 'Location', json_url( '/pods/' . $pod . '/' . $id ) );
170 |
171 | return $response;
172 | }
173 | else {
174 | return new WP_Error( 'pods_json_api_error_' . __FUNCTION__, __( 'Error adding pod item', 'pods-json-api' ) );
175 | }
176 |
177 | }
178 |
179 | /**
180 | * Get a Pod item
181 | *
182 | * @param string $pod Pod name
183 | * @param int|string $item Item ID or slug
184 | *
185 | * @return object|WP_Error
186 | *
187 | * @access public
188 | */
189 | public function get_item( $pod, $item ) {
190 |
191 | if ( !$this->check_access( __FUNCTION__, $pod, $item ) ) {
192 | return new WP_Error( 'pods_json_api_restricted_error_' . __FUNCTION__, __( 'Sorry, you do not have access to this endpoint.', 'pods-json-api' ) );
193 | }
194 |
195 | try {
196 | $pod_object = pods( $pod, $item );
197 |
198 | $data = $pod_object->export();
199 |
200 | $data = apply_filters( 'pods_json_api_pods_' . __FUNCTION__, $data, $pod, $item, $data, $pod_object );
201 |
202 | /**
203 | * pods_json_api_disable_sensitive_user_data filter is documented in the get_items method of this class.
204 | */
205 | if ( $pod === 'user' && apply_filters( 'pods_json_api_disable_sensitive_user_data', true ) ) {
206 | if ( isset( $items[ 'user_email' ] ) ) {
207 | unset( $items[ 'user_email' ] );
208 | }
209 |
210 | if ( isset( $items[ 'user_pass' ] ) ) {
211 | unset( $items[ 'user_pass' ] );
212 | }
213 | }
214 | }
215 | catch ( Exception $e ) {
216 | $data = new WP_Error( $e->getCode(), $e->getMessage() );
217 | }
218 |
219 | return $data;
220 |
221 | }
222 |
223 | /**
224 | * Save a Pod item
225 | *
226 | * @param string $pod Pod name
227 | * @param int|string $item Item ID or slug
228 | *
229 | * @return boolean|WP_Error
230 | *
231 | * @access public
232 | */
233 | public function save_item( $pod, $item, $data ) {
234 |
235 | if ( !$this->check_access( __FUNCTION__, $pod, $item ) ) {
236 | return new WP_Error( 'pods_json_api_restricted_error_' . __FUNCTION__, __( 'Sorry, you do not have access to this endpoint.', 'pods-json-api' ) );
237 | }
238 |
239 | try {
240 | $id = pods( $pod, $item )->save( $data );
241 | }
242 | catch ( Exception $e ) {
243 | $id = new WP_Error( $e->getCode(), $e->getMessage() );
244 | }
245 |
246 | if ( $id instanceof WP_Error || !function_exists( 'json_ensure_response' ) ) {
247 | return $id;
248 | }
249 | elseif ( 0 < $id ) {
250 | $response = json_ensure_response( $this->get_item( $pod, $id ) );
251 | $response->set_status( 201 );
252 | $response->header( 'Location', json_url( '/pods/' . $pod . '/' . $id ) );
253 |
254 | return $response;
255 | }
256 | else {
257 | return new WP_Error( 'pods_json_api_error_' . __FUNCTION__, __( 'Error saving pod item', 'pods-json-api' ) );
258 | }
259 |
260 | }
261 |
262 | /**
263 | * Delete a Pod item
264 | *
265 | * @param string $pod Pod name
266 | * @param int|string $item Item ID or slug
267 | *
268 | * @return boolean|WP_Error
269 | *
270 | * @access public
271 | */
272 | public function delete_item( $pod, $item ) {
273 |
274 | if ( !$this->check_access( __FUNCTION__, $pod, $item ) ) {
275 | return new WP_Error( 'pods_json_api_restricted_error_' . __FUNCTION__, __( 'Sorry, you do not have access to this endpoint.', 'pods-json-api' ) );
276 | }
277 |
278 | try {
279 | $deleted = pods( $pod, $item )->delete();
280 | }
281 | catch ( Exception $e ) {
282 | $deleted = new WP_Error( $e->getCode(), $e->getMessage() );
283 | }
284 |
285 | if ( $deleted instanceof WP_Error ) {
286 | return $deleted;
287 | }
288 | elseif ( $deleted ) {
289 | return true;
290 | }
291 | else {
292 | return new WP_Error( 'pods_json_api_error_' . __FUNCTION__, __( 'Error deleting pod item', 'pods-json-api' ) );
293 | }
294 |
295 | }
296 |
297 | /**
298 | * Duplicate a Pod item
299 | *
300 | * @param string $pod Pod name
301 | * @param int|string $item Item ID or slug
302 | *
303 | * @return boolean|WP_Error
304 | *
305 | * @access public
306 | */
307 | public function duplicate_item( $pod, $item ) {
308 |
309 | if ( !$this->check_access( __FUNCTION__, $pod, $item ) ) {
310 | return new WP_Error( 'pods_json_api_restricted_error_' . __FUNCTION__, __( 'Sorry, you do not have access to this endpoint.', 'pods-json-api' ) );
311 | }
312 |
313 | try {
314 | $id = pods( $pod, $item )->duplicate();
315 | }
316 | catch ( Exception $e ) {
317 | $id = new WP_Error( $e->getCode(), $e->getMessage() );
318 | }
319 |
320 | if ( $id instanceof WP_Error || !function_exists( 'json_ensure_response' ) ) {
321 | return $id;
322 | }
323 | elseif ( 0 < $id ) {
324 | $response = json_ensure_response( $this->get_item( $pod, $id ) );
325 | $response->set_status( 201 );
326 | $response->header( 'Location', json_url( '/pods/' . $pod . '/' . $id ) );
327 |
328 | return $response;
329 | }
330 | else {
331 | return new WP_Error( 'pods_json_api_error_' . __FUNCTION__, __( 'Error duplicating pod item', 'pods-json-api' ) );
332 | }
333 |
334 | }
335 |
336 | /**
337 | * Check if user has access to endpoint
338 | *
339 | * @param string $method Method name
340 | * @param string $pod Pod name
341 | * @param int|string $item Item ID or slug
342 | *
343 | * @return boolean If user has access
344 | *
345 | * @access protected
346 | */
347 | protected function check_access( $method, $pod = null, $item = 0 ) {
348 |
349 | $access_caps = array(
350 | 'pods'
351 | );
352 |
353 | if ( $method ) {
354 | $access_caps[] = 'pods_content';
355 | }
356 |
357 | if ( $pod ) {
358 | if ( in_array( $method, array( 'add_item', 'duplicate_item' ) ) ) {
359 | $access_caps[] = 'pods_add_' . $pod;
360 | }
361 | elseif ( 'save_item' == $method ) {
362 | $access_caps[] = 'pods_edit_' . $pod;
363 | }
364 | elseif ( 'delete_item' == $method ) {
365 | $access_caps[] = 'pods_delete_' . $pod;
366 | }
367 | }
368 |
369 | $access = pods_is_admin( $access_caps );
370 |
371 | $access = apply_filters( 'pods_json_api_access_pods_' . $method, $access, $method, $pod, $item );
372 | $access = apply_filters( 'pods_json_api_access_pods', $access, $method, $pod, $item );
373 |
374 | return $access;
375 |
376 | }
377 |
378 | }
--------------------------------------------------------------------------------
/classes/Pods/JSON/API/Pods/API.php:
--------------------------------------------------------------------------------
1 | [\w\-\_]+)' ] = array(
24 | array( array( $this, 'get_pod' ), WP_JSON_Server::READABLE ),
25 | array( array( $this, 'delete_pod' ), WP_JSON_Server::DELETABLE ),
26 |
27 | );
28 |
29 | $routes[ '/pods-api/(?P[\w\-\_]+)/duplicate' ] = array(
30 | array( array( $this, 'duplicate_pod' ), WP_JSON_Server::CREATABLE | WP_JSON_Server::ACCEPT_JSON )
31 | );
32 |
33 | $routes[ '/pods-api/(?P[\w\-\_]+)/reset' ] = array(
34 | array( array( $this, 'reset' ), WP_JSON_Server::EDITABLE | WP_JSON_Server::ACCEPT_JSON )
35 | );
36 |
37 | $routes[ '/pods-api/update_rel' ] = array(
38 | array( array( $this, 'update_rel' ), WP_JSON_Server::CREATABLE | WP_JSON_Server::ACCEPT_JSON )
39 | );
40 |
41 |
42 |
43 | return $routes;
44 |
45 | }
46 |
47 | /**
48 | * Get All Pods
49 | *
50 | * @return array
51 | *
52 | * @access public
53 | */
54 | public function get_pods() {
55 |
56 | if ( !$this->check_access( __FUNCTION__ ) ) {
57 | return new WP_Error( 'pods_json_api_restricted_error_' . __FUNCTION__, __( 'Sorry, you do not have access to this endpoint.', 'pods-json-api' ) );
58 | }
59 |
60 | $api = pods_api();
61 | $api->display_errors = false;
62 |
63 | $all_pods = $api->load_pods();
64 |
65 | $pods_to_list = array();
66 |
67 | foreach ( $all_pods as $pod ) {
68 | $pods_to_list[] = get_object_vars( $this->cleanup_pod( $pod, false ) );
69 | }
70 |
71 | return $pods_to_list;
72 |
73 | }
74 |
75 | /**
76 | * Add a Pod
77 | *
78 | * @param array $data Pod data. Can contain:
79 | * - name
80 | * - type
81 | * - =
82 | *
83 | * @return boolean|WP_Error
84 | *
85 | * @access public
86 | */
87 | public function add_pod( $data ) {
88 |
89 | if ( !$this->check_access( __FUNCTION__ ) ) {
90 | return new WP_Error( 'pods_json_api_restricted_error_' . __FUNCTION__, __( 'Sorry, you do not have access to this endpoint.', 'pods-json-api' ) );
91 | }
92 |
93 | if ( isset( $data[ 'id' ] ) ) {
94 | unset( $data[ 'id' ] );
95 | }
96 |
97 | try {
98 | $api = pods_api();
99 | $api->display_errors = false;
100 |
101 | $id = $api->save_pod( $data );
102 | }
103 | catch ( Exception $e ) {
104 | $id = new WP_Error( $e->getCode(), $e->getMessage() );
105 | }
106 |
107 | if ( $id instanceof WP_Error || !function_exists( 'json_ensure_response' ) ) {
108 | return $id;
109 | }
110 | elseif ( 0 < $id ) {
111 | $response = json_ensure_response( $pod = $this->get_pod( $id ) );
112 | $response->set_status( 201 );
113 | $response->header( 'Location', json_url( '/pods-api/' . $pod[ 'name' ] ) );
114 |
115 | return $response;
116 | }
117 | else {
118 | return new WP_Error( 'pods_json_api_error_' . __FUNCTION__, __( 'Error adding pod', 'pods-json-api' ) );
119 | }
120 |
121 | }
122 |
123 | /**
124 | * Get a Pod
125 | *
126 | * @param string|int $pod Pod name or ID (if typed as integer)
127 | *
128 | * @return object|WP_Error
129 | *
130 | * @access public
131 | */
132 | public function get_pod( $pod ) {
133 |
134 | if ( !$this->check_access( __FUNCTION__ ) ) {
135 | return new WP_Error( 'pods_json_api_restricted_error_' . __FUNCTION__, __( 'Sorry, you do not have access to this endpoint.', 'pods-json-api' ) );
136 | }
137 |
138 | try {
139 | $api = pods_api();
140 | $api->display_errors = false;
141 |
142 | $params = array();
143 |
144 | if ( is_int( $pod ) ) {
145 | $params[ 'id' ] = $pod;
146 | }
147 | else {
148 | $params[ 'name' ] = $pod;
149 | }
150 |
151 | $pod = $api->load_pod( $params );
152 | }
153 | catch ( Exception $e ) {
154 | $pod = new WP_Error( $e->getCode(), $e->getMessage() );
155 | }
156 |
157 | if ( $pod instanceof WP_Error ) {
158 | return $pod;
159 | }
160 | elseif ( $pod ) {
161 | return get_object_vars( $this->cleanup_pod( $pod ) );
162 | }
163 | else {
164 | return new WP_Error( 'pods_json_api_error_' . __FUNCTION__, __( 'Error getting pod', 'pods-json-api' ) );
165 | }
166 |
167 | }
168 |
169 | /**
170 | * Save a Pod
171 | *
172 | * @param string|int $pod Pod name or ID (if typed as integer)
173 | * @param array $data Pod data. Can contain:
174 | * - =
175 | *
176 | * @return boolean|WP_Error
177 | *
178 | * @access public
179 | */
180 | public function save_pod( $pod, $data ) {
181 |
182 | if ( !$this->check_access( __FUNCTION__ ) ) {
183 | return new WP_Error( 'pods_json_api_restricted_error_' . __FUNCTION__, __( 'Sorry, you do not have access to this endpoint.', 'pods-json-api' ) );
184 | }
185 |
186 | try {
187 | $api = pods_api();
188 | $api->display_errors = false;
189 |
190 | if ( is_int( $pod ) ) {
191 | $data[ 'id' ] = $pod;
192 | }
193 | else {
194 | $data[ 'name' ] = $pod;
195 | }
196 |
197 | $id = $api->save_pod( $data );
198 | }
199 | catch ( Exception $e ) {
200 | $id = new WP_Error( $e->getCode(), $e->getMessage() );
201 | }
202 |
203 | if ( $id instanceof WP_Error || !function_exists( 'json_ensure_response' ) ) {
204 | return $id;
205 | }
206 | elseif ( 0 < $id ) {
207 | $response = json_ensure_response( $pod = $this->get_pod( $id ) );
208 | $response->set_status( 201 );
209 | $response->header( 'Location', json_url( '/pods-api/' . $pod[ 'name' ] ) );
210 |
211 | return $response;
212 | }
213 | else {
214 | return new WP_Error( 'pods_json_api_error_' . __FUNCTION__, __( 'Error saving pod', 'pods-json-api' ) );
215 | }
216 |
217 | }
218 |
219 | /**
220 | * Delete a Pod
221 | *
222 | * @param string|int $pod Pod name or ID (if typed as integer)
223 | *
224 | * @return boolean|WP_Error
225 | *
226 | * @access public
227 | */
228 | public function delete_pod( $pod ) {
229 |
230 | if ( !$this->check_access( __FUNCTION__ ) ) {
231 | return new WP_Error( 'pods_json_api_restricted_error_' . __FUNCTION__, __( 'Sorry, you do not have access to this endpoint.', 'pods-json-api' ) );
232 | }
233 |
234 | try {
235 | $api = pods_api();
236 | $api->display_errors = false;
237 |
238 | $params = array();
239 |
240 | if ( is_int( $pod ) ) {
241 | $params[ 'id' ] = $pod;
242 | }
243 | else {
244 | $params[ 'name' ] = $pod;
245 | }
246 |
247 | $deleted = $api->delete_pod( $params );
248 | }
249 | catch ( Exception $e ) {
250 | $deleted = new WP_Error( $e->getCode(), $e->getMessage() );
251 | }
252 |
253 | if ( $deleted instanceof WP_Error ) {
254 | return $deleted;
255 | }
256 | elseif ( $deleted ) {
257 | return true;
258 | }
259 | else {
260 | return new WP_Error( 'pods_json_api_error_' . __FUNCTION__, __( 'Error deleting pod', 'pods-json-api' ) );
261 | }
262 |
263 | }
264 |
265 | /**
266 | * Duplicate a Pod
267 | *
268 | * @param string|int $pod Pod name or ID (if typed as integer)
269 | * @param array $data Pod data. Can contain:
270 | * - new_name
271 | * - =
272 | *
273 | * @return boolean|WP_Error
274 | *
275 | * @access public
276 | */
277 | public function duplicate_pod( $pod, $data = array() ) {
278 |
279 | if ( !$this->check_access( __FUNCTION__ ) ) {
280 | return new WP_Error( 'pods_json_api_restricted_error_' . __FUNCTION__, __( 'Sorry, you do not have access to this endpoint.', 'pods-json-api' ) );
281 | }
282 |
283 | try {
284 | $api = pods_api();
285 | $api->display_errors = false;
286 |
287 | if ( is_int( $pod ) ) {
288 | $data[ 'id' ] = $pod;
289 | }
290 | else {
291 | $data[ 'name' ] = $pod;
292 | }
293 |
294 | $id = $api->duplicate_pod( $data );
295 | }
296 | catch ( Exception $e ) {
297 | $id = new WP_Error( $e->getCode(), $e->getMessage() );
298 | }
299 |
300 | if ( $id instanceof WP_Error || !function_exists( 'json_ensure_response' ) ) {
301 | return $id;
302 | }
303 | elseif ( 0 < $id ) {
304 | $response = json_ensure_response( $pod = $this->get_pod( $id ) );
305 | $response->set_status( 201 );
306 | $response->header( 'Location', json_url( '/pods-api/' . $pod[ 'name' ] ) );
307 |
308 | return $response;
309 | }
310 | else {
311 | return new WP_Error( 'pods_json_api_error_' . __FUNCTION__, __( 'Error duplicating pod', 'pods-json-api' ) );
312 | }
313 |
314 | }
315 |
316 | /**
317 | * Reset a Pod's contents
318 | *
319 | * @param string|int $pod Pod name or ID (if typed as integer)
320 | *
321 | * @return boolean|WP_Error
322 | *
323 | * @access public
324 | */
325 | public function reset_pod( $pod ) {
326 |
327 | if ( !$this->check_access( __FUNCTION__ ) ) {
328 | return new WP_Error( 'pods_json_api_restricted_error_' . __FUNCTION__, __( 'Sorry, you do not have access to this endpoint.', 'pods-json-api' ) );
329 | }
330 |
331 | try {
332 | $api = pods_api();
333 | $api->display_errors = false;
334 |
335 | $params = array();
336 |
337 | if ( is_int( $pod ) ) {
338 | $params[ 'id' ] = $pod;
339 | }
340 | else {
341 | $params[ 'name' ] = $pod;
342 | }
343 |
344 | $reset = $api->reset_pod( $params );
345 | }
346 | catch ( Exception $e ) {
347 | $reset = new WP_Error( $e->getCode(), $e->getMessage() );
348 | }
349 |
350 | if ( $reset instanceof WP_Error ) {
351 | return $reset;
352 | }
353 | elseif ( $reset ) {
354 | return true;
355 | }
356 | else {
357 | return new WP_Error( 'pods_json_api_error_' . __FUNCTION__, __( 'Error resetting pod', 'pods-json-api' ) );
358 | }
359 |
360 | }
361 |
362 | /**
363 | * Update bi-directional relationships to correct sister IDs.
364 | *
365 | * @see Readme for structure of data.
366 | *
367 | * @param int|string $pod Pod name or Pod ID.
368 | * @param array $data Array of relationships for site
369 | *
370 | *
371 | * @access public
372 | *
373 | * @return WP_Error|WP_JSON_ResponseInterface
374 | */
375 | function update_rel( $data = array() ) {
376 | if ( ! $this->check_access( __FUNCTION__ ) ) {
377 | return new WP_Error( 'pods_json_api_restricted_error_' . __FUNCTION__, __( 'Sorry, you do not have access to this endpoint.', 'pods-json-api' ) );
378 | }
379 | try {
380 | $id = $other_pods = $fields_updated = false;
381 | $api = pods_api();
382 | $api->display_errors = false;
383 |
384 | $pod_names = $api->load_pods( array( 'names' => true ) );
385 | if ( ! empty( $pod_names ) ) {
386 | $pod_names = array_flip( (array) $pod_names );
387 | }
388 |
389 | foreach ( $data as $relates ) {
390 | $pod = $relates[ 'from' ][ 'pod_name' ];
391 | $this_pod = $api->load_pod( array( 'name' => $pod ) );
392 | $pod_id = $id = pods_v( 'id', $this_pod );
393 | $fields = pods_v( 'fields', $this_pod );
394 | unset( $this_pod );
395 |
396 | $other_pods = $fields_updated = array ();
397 | foreach( $fields as $field ) {
398 | if ( 'pick' == pods_v( 'type', $field ) ) {
399 | $field_id = pods_v( 'id', $field );
400 | $field_name = pods_v( 'name', $field );
401 | $to_pod = pods_v( 'pick_val', $field );
402 |
403 | if ( in_array( $to_pod, $pod_names ) ) {
404 |
405 | $relationship = pods_v( $pod . '_' . pods_v( 'name', $field ), $data );
406 | $to_pod = $relationship[ 'to' ][ 'pod_name' ];
407 | $to_field = $relationship[ 'to' ][ 'field_name' ];
408 |
409 | if ( is_null( $related_pod = pods_v( $to_pod, $other_pods ) ) ) {
410 | $params = array( 'name' => $to_pod );
411 | $related_pod = $api->load_pod( $params );
412 | $related_pod = pods_v( 'fields', $related_pod );
413 | if ( is_object( $related_pod ) && ! empty ( $related_pod ) ) {
414 | $other_pods[ $to_pod ] = $related_pod;
415 | }
416 |
417 | $field = pods_v( $to_field, $related_pod );
418 | $sister_id = pods_v( 'id', $field );
419 |
420 | if ( ! is_null( $pod_id ) && ! is_null( $field_id ) && ! is_null( $sister_id ) && ! is_null( $field_name ) ) {
421 | $params = array (
422 | 'pod_id' => $pod_id,
423 | 'id' => $field_id,
424 | 'sister_id' => $sister_id,
425 | 'name' => $field_name,
426 | );
427 | }
428 |
429 | $fields_updated[] = $api->save_field( $params );
430 |
431 | }
432 |
433 | }
434 |
435 | }
436 |
437 | }
438 | }
439 | }
440 | catch ( Exception $e ) {
441 | $id = new WP_Error( $e->getCode(), $e->getMessage() );
442 | }
443 |
444 | if ( $id instanceof WP_Error || !function_exists( 'json_ensure_response' ) ) {
445 | return $id;
446 | }
447 | elseif( isset( $fields_updated ) && is_array( $fields_updated ) ) {
448 | return $fields_updated;
449 | $response = json_ensure_response( $fields_updated );
450 | $response->set_status( 201 );
451 | $response->header( 'Location', json_url( '/pods-api/' . $pod[ 'name' ] . '/' . __FUNCTION__ ) );
452 |
453 | return $response;
454 | }
455 | elseif ( 0 < $id ) {
456 | $response = json_ensure_response( $pod = $this->get_pod( $id ) );
457 | $response->set_status( 201 );
458 | $response->header( 'Location', json_url( '/pods-api/' . $pod[ 'name' ] . '/' . __FUNCTION__ ) );
459 |
460 | return $response;
461 | }
462 | else {
463 | return new WP_Error( 'pods_json_api_error_' . __FUNCTION__, __( 'Error updating relationship', 'pods-json-api' ) );
464 | }
465 |
466 | }
467 |
468 | /**
469 | * Import a Pods Migrate package
470 | *
471 | * Pods Package component must be active on site receiving data or an error will be returned.
472 | *
473 | * @param array $data Pods Migrate Package.
474 | *
475 | * @return boolean|WP_Error
476 | *
477 | * @access public
478 | */
479 | public function package( $data ) {
480 | return new WP_Error( 'pods_json_api_error_' . __FUNCTION__ . 'no_package', __( 'This endpoint requires activating the Pods Packages component on the site receiving the package.', 'pods-json-api' ) );
481 | if ( ! $this->check_access( __FUNCTION__ ) ) {
482 | return new WP_Error( 'pods_json_api_restricted_error_' . __FUNCTION__, __( 'Sorry, you do not have access to this endpoint.', 'pods-json-api' ) );
483 | }
484 |
485 | if ( ! class_exists( 'Pods_Migrate_Packages' ) ) {
486 | return new WP_Error( 'pods_json_api_error_' . __FUNCTION__ . 'no_package', __( 'This endpoint requires activating the Pods Packages component on the site receiving the package.', 'pods-json-api' ) );
487 | }
488 |
489 | try {
490 |
491 | $id = Pods_Migrate_Packages::import( $data );
492 |
493 | }
494 | catch ( Exception $e ) {
495 | $id = new WP_Error( $e->getCode(), $e->getMessage() );
496 | }
497 |
498 | if ( $id instanceof WP_Error || !function_exists( 'json_ensure_response' ) ) {
499 | return $id;
500 | }
501 | elseif ( 0 < $id ) {
502 | $response = json_ensure_response( $id );
503 | $response->set_status( 201 );
504 | $response->header( 'Location', json_url( '/pods-api/package' ) );
505 |
506 | return $response;
507 | }
508 | else {
509 | return new WP_Error( 'pods_json_api_error_' . __FUNCTION__, __( 'Error importing package.', 'pods-json-api' ) );
510 | }
511 |
512 | }
513 |
514 | /**
515 | * Check if user has access to endpoint
516 | *
517 | * @param string $method Method name
518 | *
519 | * @return boolean If user has access
520 | *
521 | * @access protected
522 | */
523 | protected function check_access( $method ) {
524 |
525 | $access = pods_is_admin( array( 'pods' ) );
526 |
527 | $access = apply_filters( 'pods_json_api_access_api_' . $method, $access, $method );
528 | $access = apply_filters( 'pods_json_api_access_api', $access, $method );
529 |
530 | return $access;
531 |
532 | }
533 |
534 | /**
535 | * Cleanup Pod data for return
536 | *
537 | * @param array $pod Pod array
538 | * @param boolean $fields Include fields in pod
539 | *
540 | * @return object
541 | *
542 | * @access protected
543 | */
544 | function cleanup_pod( $pod, $fields = true ) {
545 |
546 | $options_ignore = array(
547 | 'pod_id',
548 | 'old_name',
549 | 'object_type',
550 | 'object_name',
551 | 'object_hierarchical',
552 | 'table',
553 | 'meta_table',
554 | 'pod_table',
555 | 'field_id',
556 | 'field_index',
557 | 'field_slug',
558 | 'field_type',
559 | 'field_parent',
560 | 'field_parent_select',
561 | 'meta_field_id',
562 | 'meta_field_index',
563 | 'meta_field_value',
564 | 'pod_field_id',
565 | 'pod_field_index',
566 | 'object_fields',
567 | 'join',
568 | 'where',
569 | 'where_default',
570 | 'orderby',
571 | 'pod',
572 | 'recurse',
573 | 'table_info',
574 | 'attributes',
575 | 'group',
576 | 'grouped',
577 | 'developer_mode',
578 | 'dependency',
579 | 'depends-on',
580 | 'excludes-on'
581 | );
582 |
583 | $empties = array(
584 | 'description',
585 | 'alias',
586 | 'help',
587 | 'class',
588 | 'pick_object',
589 | 'pick_val',
590 | 'sister_id',
591 | 'required',
592 | 'unique',
593 | 'admin_only',
594 | 'restrict_role',
595 | 'restrict_capability',
596 | 'hidden',
597 | 'read_only',
598 | 'object',
599 | 'label_singular'
600 | );
601 |
602 | if ( isset( $pod[ 'options' ] ) ) {
603 | $pod = array_merge( $pod, $pod[ 'options' ] );
604 |
605 | unset( $pod[ 'options' ] );
606 | }
607 |
608 | foreach ( $pod as $option => $option_value ) {
609 | if ( in_array( $option, $options_ignore ) || null === $option_value ) {
610 | unset( $pod[ $option ] );
611 | }
612 | elseif ( in_array( $option, $empties ) && ( empty( $option_value ) || '0' == $option_value ) ) {
613 | if ( 'restrict_role' == $option && isset( $pod[ 'roles_allowed' ] ) ) {
614 | unset( $pod[ 'roles_allowed' ] );
615 | }
616 | elseif ( 'restrict_capability' == $option && isset( $pod[ 'capabilities_allowed' ] ) ) {
617 | unset( $pod[ 'capabilities_allowed' ] );
618 | }
619 |
620 | unset( $pod[ $option ] );
621 | }
622 | }
623 |
624 | if ( $fields ) {
625 | $pods_form = pods_form();
626 | $field_types = $pods_form::field_types();
627 |
628 | $field_type_options = array();
629 |
630 | foreach ( $field_types as $type => $field_type_data ) {
631 | $field_type_options[ $type ] = $pods_form::ui_options( $type );
632 | }
633 |
634 | foreach ( $pod[ 'fields' ] as &$field ) {
635 | if ( isset( $field[ 'options' ] ) ) {
636 | $field = array_merge( $field, $field[ 'options' ] );
637 |
638 | unset( $field[ 'options' ] );
639 | }
640 |
641 | foreach ( $field as $option => $option_value ) {
642 | if ( in_array( $option, $options_ignore ) || null === $option_value ) {
643 | unset( $field[ $option ] );
644 | }
645 | elseif ( in_array( $option, $empties ) && ( empty( $option_value ) || '0' == $option_value ) ) {
646 | if ( 'restrict_role' == $option && isset( $field[ 'roles_allowed' ] ) ) {
647 | unset( $field[ 'roles_allowed' ] );
648 | }
649 | elseif ( 'restrict_capability' == $option && isset( $field[ 'capabilities_allowed' ] ) ) {
650 | unset( $field[ 'capabilities_allowed' ] );
651 | }
652 |
653 | unset( $field[ $option ] );
654 | }
655 | }
656 |
657 | foreach ( $field_type_options as $type => $options ) {
658 | if ( $type == pods_v( 'type', $field ) ) {
659 | continue;
660 | }
661 |
662 | foreach ( $options as $option_data ) {
663 | if ( isset( $option_data[ 'group' ] ) && is_array( $option_data[ 'group' ] ) && !empty( $option_data[ 'group' ] ) ) {
664 | if ( isset( $field[ $option_data[ 'name' ] ] ) ) {
665 | unset( $field[ $option_data[ 'name' ] ] );
666 | }
667 |
668 | foreach ( $option_data[ 'group' ] as $group_option_data ) {
669 | if ( isset( $field[ $group_option_data[ 'name' ] ] ) ) {
670 | unset( $field[ $group_option_data[ 'name' ] ] );
671 | }
672 | }
673 | }
674 | elseif ( isset( $field[ $option_data[ 'name' ] ] ) ) {
675 | unset( $field[ $option_data[ 'name' ] ] );
676 | }
677 | }
678 | }
679 | }
680 | }
681 | else {
682 | unset( $pod[ 'fields' ] );
683 | }
684 |
685 | return (object) $pod;
686 |
687 | }
688 |
689 | }
690 |
--------------------------------------------------------------------------------
/classes/Pods/JSON/API/Pods/Components.php:
--------------------------------------------------------------------------------
1 | [\w\-\_]+)' ] = array(
27 | array( array( $this, 'activate' ), WP_JSON_Server::EDITABLE ),
28 | array( array( $this, 'deactivate' ), WP_JSON_Server::DELETABLE ),
29 | );
30 |
31 | return $routes;
32 |
33 | }
34 |
35 | /**
36 | * Import a Pods Migrate package
37 | *
38 | * Pods Package component must be active on site receiving data or an error will be returned.
39 | *
40 | * @param array $data Pods Migrate Package.
41 | *
42 | * @return boolean|WP_Error
43 | *
44 | * @access public
45 | */
46 | public function package( $data ) {
47 |
48 | if ( ! $this->check_access( __FUNCTION__ ) ) {
49 | return new WP_Error( 'pods_json_api_restricted_error_' . __FUNCTION__, __( 'Sorry, you do not have access to this endpoint.', 'pods-json-api' ) );
50 | }
51 |
52 | if ( ! class_exists( 'Pods_Migrate_Packages' ) ) {
53 | return new WP_Error( 'pods_json_api_error_' . __FUNCTION__ . 'no_package', __( 'This endpoint requires activating the Pods Packages component on the site receiving the package.', 'pods-json-api' ) );
54 | }
55 |
56 | try {
57 |
58 | $id = Pods_Migrate_Packages::import( $data );
59 |
60 | }
61 | catch ( Exception $e ) {
62 | $id = new WP_Error( $e->getCode(), $e->getMessage() );
63 | }
64 |
65 | if ( $id instanceof WP_Error || !function_exists( 'json_ensure_response' ) ) {
66 | return $id;
67 | }
68 | elseif ( 0 < $id ) {
69 | $response = json_ensure_response( $id );
70 | $response->set_status( 201 );
71 | $response->header( 'Location', json_url( '/pods-components?package' ) );
72 |
73 | return $response;
74 | }
75 | else {
76 | return new WP_Error( 'pods_json_api_error_' . __FUNCTION__, __( 'Error importing package.', 'pods-json-api' ) );
77 | }
78 |
79 | }
80 |
81 | /**
82 | * Activate a single component
83 | *
84 | * @param $component
85 | *
86 | * @since 0.2.0
87 | *
88 | * @return WP_Error|WP_JSON_ResponseInterface
89 | */
90 | function activate( $component ) {
91 |
92 | if ( ! $this->check_access( __FUNCTION__ ) ) {
93 | return new WP_Error( 'pods_json_api_restricted_error_' . __FUNCTION__, __( 'Sorry, you do not have access to this endpoint.', 'pods-json-api' ) );
94 | }
95 | try {
96 |
97 |
98 | $components = array( 0 => $component );
99 |
100 | $id = $this->enable_components( $components, true );
101 |
102 | }
103 | catch ( Exception $e ) {
104 | $id = new WP_Error( $e->getCode(), $e->getMessage() );
105 | }
106 |
107 | if ( $id instanceof WP_Error || !function_exists( 'json_ensure_response' ) ) {
108 | return $id;
109 | }
110 | elseif ( 0 < $id ) {
111 | $response = json_ensure_response( $id );
112 | $response->set_status( 201 );
113 | $response->header( 'Location', json_url( '/pods-components/activate/' . $component ) );
114 |
115 | return $response;
116 | }
117 | else {
118 | return new WP_Error( 'pods_json_api_error_' . __FUNCTION__, __( 'Error activating component.', 'pods-json-api' ) );
119 | }
120 |
121 | }
122 |
123 | /**
124 | * Deactivate a single component
125 | *
126 | * @param $component
127 | *
128 | * @since 0.2.0
129 | *
130 | * @return WP_Error|WP_JSON_ResponseInterface
131 | */
132 | function deactivate( $component ) {
133 | if ( ! $this->check_access( __FUNCTION__ ) ) {
134 | return new WP_Error( 'pods_json_api_restricted_error_' . __FUNCTION__, __( 'Sorry, you do not have access to this endpoint.', 'pods-json-api' ) );
135 | }
136 | try {
137 | $components = array( 0 => $component );
138 | $id = $this->enable_components( $components, false );
139 |
140 | }
141 | catch ( Exception $e ) {
142 | $id = new WP_Error( $e->getCode(), $e->getMessage() );
143 | }
144 |
145 | if ( $id instanceof WP_Error || !function_exists( 'json_ensure_response' ) ) {
146 | return $id;
147 | }
148 | elseif ( 0 < $id ) {
149 | $response = json_ensure_response( $id );
150 | $response->set_status( 201 );
151 | $response->header( 'Location', json_url( '/pods-components/activate/' . $component ) );
152 |
153 | return $response;
154 | }
155 | else {
156 | return new WP_Error( 'pods_json_api_error_' . __FUNCTION__, __( 'Error deactivating components.', 'pods-json-api' ) );
157 | }
158 |
159 | }
160 |
161 | /**
162 | * Activate and/or deactivate components
163 | *
164 | * @param array $data A multi-dimensional array containing a 'activate' and or 'deactivate' key, each of which should contain an array of Pods Component names.
165 | *
166 | * @since 0.2
167 | *
168 | * @return WP_Error|WP_JSON_ResponseInterface
169 | */
170 | function activate_components( $data ) {
171 |
172 | if ( ! $this->check_access( __FUNCTION__ ) ) {
173 | return new WP_Error( 'pods_json_api_restricted_error_' . __FUNCTION__, __( 'Sorry, you do not have access to this endpoint.', 'pods-json-api' ) );
174 | }
175 | try {
176 | $id = 0;
177 |
178 | //activate components
179 | if ( ! is_null( $components = pods_v( 'activate', $data ) ) && is_array( $components ) ) {
180 |
181 | $id = $this->enable_components( $components, true );
182 |
183 | }
184 |
185 | //deactivate components
186 | if ( ! is_null( $components = pods_v( 'deactivate', $data ) ) && is_array( $components ) ) {
187 |
188 | $id = $this->enable_components( $data, false );
189 |
190 | }
191 |
192 |
193 | }
194 | catch ( Exception $e ) {
195 | $id = new WP_Error( $e->getCode(), $e->getMessage() );
196 | }
197 |
198 | if ( $id instanceof WP_Error || !function_exists( 'json_ensure_response' ) ) {
199 | return $id;
200 | }
201 | elseif ( 0 < $id ) {
202 | $response = json_ensure_response( $id );
203 | $response->set_status( 201 );
204 | $response->header( 'Location', json_url( '/pods-components?activate_components' ) );
205 |
206 | return $response;
207 | }
208 | else {
209 | return null;
210 | }
211 | }
212 |
213 | /**
214 | * Returns an array of all components. Key is component ID, value is true if active, false if inactive.
215 | *
216 | * @since 0.2.0
217 | *
218 | * @return mixed
219 | */
220 | function get_components() {
221 | if ( ! $this->check_access( __FUNCTION__ ) ) {
222 | return new WP_Error( 'pods_json_api_restricted_error_' . __FUNCTION__, __( 'Sorry, you do not have access to this endpoint.', 'pods-json-api' ) );
223 | }
224 |
225 | $components = new PodsComponents();
226 | $components = $components->get_components();
227 | $components = array_keys( wp_list_pluck( $components, 'ID' ));
228 | $active_components = get_option( 'pods_component_settings' );
229 | $active_components = json_decode( $active_components );
230 | $active_components = pods_v( 'components', $active_components );
231 | if ( $active_components ) {
232 | $active_components = array_keys( (array) $active_components );
233 | }
234 |
235 | try {
236 | if ( ! is_null( $active_components ) ) {
237 | foreach ( $components as $component ) {
238 |
239 | if ( in_array( $component, $active_components ) ) {
240 | $response[ $component ] = true;
241 | } else {
242 | $response[ $component ] = false;
243 | }
244 | }
245 | } else {
246 | $response = 0;
247 | }
248 |
249 | }
250 | catch ( Exception $e ) {
251 | $response = new WP_Error( $e->getCode(), $e->getMessage() );
252 | }
253 |
254 | if ( $response instanceof WP_Error || !function_exists( 'json_ensure_response' ) ) {
255 | return $response;
256 | }
257 | elseif ( 0 < $response ) {
258 | $response = json_ensure_response( $response );
259 | $response->set_status( 201 );
260 | $response->header( 'Location', json_url( '/pods-components?get_components' ) );
261 |
262 | return $response;
263 | }
264 | else {
265 |
266 | return null;
267 |
268 | }
269 |
270 |
271 |
272 | }
273 |
274 | /**
275 | * Check if user has access to endpoint
276 | *
277 | * @param string $method Method name
278 | *
279 | * @return boolean If user has access
280 | *
281 | * @access protected
282 | */
283 | protected function check_access( $method ) {
284 |
285 | $access = pods_is_admin( array( 'pods' ) );
286 |
287 | $access = apply_filters( 'pods_json_api_access_components_' . $method, $access, $method );
288 | $access = apply_filters( 'pods_json_api_access_components', $access, $method );
289 |
290 | return $access;
291 |
292 | }
293 |
294 | /**
295 | * Enable or disable a component
296 | *
297 | * @since 0.2
298 | *
299 | * @access private
300 | *
301 | * @return bool True if option updated, false if not.
302 | */
303 | private function enable_components( $components, $activate = true ) {
304 | $component_settings = PodsInit::$components->settings;
305 | if ( ! is_array( $components ) ) {
306 | return;
307 | }
308 |
309 | if ( ! isset( $component_settings[ 'components' ] ) ) {
310 | $component_settings = array( 'components' );
311 | }
312 |
313 | foreach( $components as $component ) {
314 |
315 | if ( $activate ) {
316 | $component_settings[ 'components' ][ $component ] = array ();
317 | }
318 | else {
319 | if ( is_array( $component ) ) {
320 | foreach ( $component as $c ) {
321 | if ( isset( $component_settings[ 'components' ][ $c ] ) ) {
322 | unset( $component_settings[ 'components' ][ $c ] );
323 | }
324 | }
325 | }
326 | else {
327 | if ( isset( $component_settings[ 'components' ][ $component ] ) ) {
328 | unset( $component_settings[ 'components' ][ $component ] );
329 | }
330 | }
331 |
332 |
333 |
334 | }
335 |
336 | }
337 |
338 | return update_option( 'pods_component_settings', json_encode( $component_settings ) );
339 |
340 | }
341 |
342 |
343 | }
344 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "pods-framework/pods-json-api",
3 | "description": "JSON REST API for Pods. This plugin creates JSON API endpoints for https://github.com/WP-API/WP-API",
4 | "type": "wordpress-plugin",
5 | "keywords": ["pods", "wordpress", "wp-api", "api"],
6 | "homepage": "https://github.com/pods-framework/pods-json-api",
7 | "require": {
8 | "php": ">=5.3"
9 | },
10 | "license": "GPL-2.0",
11 | "authors": [
12 | {
13 | "name": "Scott Kingsley Clark",
14 | "email": "lol@scottkclark.com",
15 | "homepage": "http://scottkclark.com",
16 | "role" : "Lead Developer"
17 | },
18 | {
19 | "name": "Pods Framework Team",
20 | "email": "contact@pods.io",
21 | "homepage": "http://pods.io/"
22 | }
23 | ],
24 | "support": {
25 | "issues": "https://github.com/pods-framework/pods-json-api/issues",
26 | "source": "https://github.com/pods-framework/pods-json-api"
27 | },
28 | "require": {
29 | "composer/installers": "~1.0"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/pods-json-api.php:
--------------------------------------------------------------------------------
1 |
%s
',
59 | sprintf(
60 | __( '%1$s requires the Pods plugin to be installed/activated.', 'pods-json-api' ),
61 | 'Pods JSON API' )
62 | );
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/readme.txt:
--------------------------------------------------------------------------------
1 | === Pods JSON API ===
2 | Contributors: sc0ttkclark, modemlooper, shelob9
3 | Tags: pods, json, api
4 | Tested up to: 4.0
5 | Stable tag: 0.2.3
6 | Version: 0.2.3
7 | License: GPLv2
8 |
9 | == Description ==
10 | JSON REST API for Pods. This plugin creates JSON API endpoints for https://github.com/WP-API/WP-API
11 |
12 | == Installation ==
13 |
14 | 1. Unpack the entire contents of this plugin zip file into your `wp-content/plugins/` folder locally
15 | 1. Upload to your site
16 | 1. Navigate to `wp-admin/plugins.php` on your site (your WP Admin plugin page)
17 | 1. Activate this plugin
18 |
19 | OR you can just install it with WordPress by going to Plugins >> Add New >> and type this plugin's name
20 |
21 | == Screenshots ==
22 |
23 |
24 | == Notes ==
25 |
26 |
27 | == Changelog ==
28 | = 0.1 - May 27th, 2014 =
29 | * Initial release
30 | = 0.2 - September 20, 2014 =
31 | * Add 'update_rel' endpoint
32 | * Add 'package' endpoint'
33 |
--------------------------------------------------------------------------------