├── log.txt
├── .gitignore
├── libs
└── parse.com-php-library
│ ├── parseGeoPoint.php
│ ├── parseConfig.php
│ ├── parseFile.php
│ ├── parseACL.php
│ ├── parseObject.php
│ ├── parsePush.php
│ ├── parseUser.php
│ ├── parse.php
│ └── parseQuery.php
├── includes
├── class-wp-parse-api-admin-settings.php
├── class-wp-parse-api-helpers.php
└── class-wp-parse-api-admin-settings-template.php
├── wp-parse-api.php
└── Readme.md
/log.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | log
2 |
--------------------------------------------------------------------------------
/libs/parse.com-php-library/parseGeoPoint.php:
--------------------------------------------------------------------------------
1 | lat = $lat;
11 | $this->long = $long;
12 | $this->location = $this->dataType('geopoint', array($this->lat, $this->long));
13 | }
14 |
15 | public function __toString(){
16 | return json_encode($this->location);
17 |
18 | }
19 |
20 | public function get(){
21 | return json_encode($this->location);
22 |
23 | }
24 |
25 | }
26 |
27 | ?>
28 |
--------------------------------------------------------------------------------
/libs/parse.com-php-library/parseConfig.php:
--------------------------------------------------------------------------------
1 | _contentType = $contentType;
11 | $this->data = $data;
12 | }
13 |
14 | parent::__construct();
15 |
16 | }
17 |
18 | public function save($fileName){
19 | if($fileName != '' && $this->_contentType != '' && $this->data != ''){
20 | $request = $this->request(array(
21 | 'method' => 'POST',
22 | 'requestUrl' => 'files/'.$fileName,
23 | 'contentType' => $this->_contentType,
24 | 'data' => $this->data,
25 | ));
26 | return $request;
27 | }
28 | else{
29 | $this->throwError('Please make sure you are passing a proper filename as string (e.g. hello.txt)');
30 | }
31 | }
32 |
33 | public function delete($parseFileName){
34 | if($parseFileName != ''){
35 | $request = $this->request(array(
36 | 'method' => 'DELETE',
37 | 'requestUrl' => 'files/'.$parseFileName,
38 | 'contentType' => $this->_contentType,
39 | ));
40 | return $request;
41 |
42 | }
43 | }
44 |
45 |
46 |
47 | }
48 |
49 | ?>
--------------------------------------------------------------------------------
/libs/parse.com-php-library/parseACL.php:
--------------------------------------------------------------------------------
1 | __set('hello','world');
6 |
7 | // This instantiates a ACL object with NO rights!
8 | $acl = new parseACL();
9 | $acl->setPublicReadAccess(false);
10 | $acl->setReadAccessForId('user_id',true);
11 | $acl->setWriteAccessForRole('role_name',true);
12 |
13 | $object->ACL($acl);
14 | $object->save();
15 | */
16 | class parseACL{
17 | public $acl;
18 | public function __construct(){
19 | $this->acl = new stdClass();
20 | }
21 | private function setAccessForKey($access,$key,$bool){
22 | if(!($access == 'read' || $access == 'write')) return;
23 | if(is_object($this->acl)) $this->acl = array();
24 | if($bool) $this->acl[$key][$access] = true;
25 | else {
26 | if(isset($this->acl[$key])){
27 | unset($this->acl[$key][$access]);
28 | if(sizeof($this->acl[$key]) == 0) unset($this->acl[$key]);
29 | }
30 | if(sizeof($this->acl) == 0) $this->acl = new stdClass();
31 | }
32 | }
33 | public function setPublicReadAccess($bool){
34 | $this->setAccessForKey('read','*',$bool);
35 | }
36 | public function setPublicWriteAccess($bool){
37 | $this->setAccessForKey('write','*',$bool);
38 | }
39 | public function setReadAccessForId($userId,$bool){
40 | $this->setAccessForKey('read',$userId,$bool);
41 | }
42 | public function setWriteAccessForId($userId,$bool){
43 | $this->setAccessForKey('write',$userId,$bool);
44 | }
45 | public function setReadAccessForRole($role,$bool){
46 | $this->setAccessForKey('read','role:'.$role,$bool);
47 | }
48 | public function setWriteAccessForRole($role,$bool){
49 | $this->setAccessForKey('write','role:'.$role,$bool);
50 | }
51 | }
52 | ?>
--------------------------------------------------------------------------------
/libs/parse.com-php-library/parseObject.php:
--------------------------------------------------------------------------------
1 | _className = $class;
10 | }
11 | else{
12 | $this->throwError('include the className when creating a parseObject');
13 | }
14 |
15 | parent::__construct();
16 | }
17 |
18 | public function __set($name,$value){
19 | if($name != '_className'){
20 | $this->data[$name] = $value;
21 | }
22 | }
23 |
24 | public function save(){
25 | if(count($this->data) > 0 && $this->_className != ''){
26 | $request = $this->request(array(
27 | 'method' => 'POST',
28 | 'requestUrl' => 'classes/'.$this->_className,
29 | 'data' => $this->data,
30 | ));
31 | return $request;
32 | }
33 | }
34 |
35 | public function get($id){
36 | if($this->_className != '' || !empty($id)){
37 | $request = $this->request(array(
38 | 'method' => 'GET',
39 | 'requestUrl' => 'classes/'.$this->_className.'/'.$id
40 | ));
41 |
42 | if(!empty($this->_includes)){
43 | $request['include'] = implode(',', $this->_includes);
44 | }
45 |
46 | return $request;
47 | }
48 | }
49 |
50 | public function update($id){
51 | if($this->_className != '' || !empty($id)){
52 | $request = $this->request(array(
53 | 'method' => 'PUT',
54 | 'requestUrl' => 'classes/'.$this->_className.'/'.$id,
55 | 'data' => $this->data,
56 | ));
57 |
58 | return $request;
59 | }
60 | }
61 |
62 | public function increment($field,$amount){
63 | $this->data[$field] = $this->dataType('increment', $amount);
64 | }
65 |
66 | public function decrement($id){
67 | $this->data[$field] = $this->dataType('decrement', $amount);
68 | }
69 |
70 |
71 | public function delete($id){
72 | if($this->_className != '' || !empty($id)){
73 | $request = $this->request(array(
74 | 'method' => 'DELETE',
75 | 'requestUrl' => 'classes/'.$this->_className.'/'.$id
76 | ));
77 |
78 | return $request;
79 | }
80 | }
81 |
82 | public function addInclude($name){
83 | $this->_includes[] = $name;
84 | }
85 | }
86 |
87 | ?>
--------------------------------------------------------------------------------
/libs/parse.com-php-library/parsePush.php:
--------------------------------------------------------------------------------
1 | _globalMsg = $globalMsg;
18 | }
19 |
20 | parent::__construct();
21 |
22 | }
23 |
24 | public function __set($name,$value){
25 | if($name != 'channel' || $name != 'channels' || $name != 'expiration_time' || $name != 'expiration_interval' || $name != 'type' || $name != 'data'){
26 | $this->data[$name] = $value;
27 | }
28 | }
29 |
30 | public function send(){
31 | if($this->_globalMsg != ''){
32 | $request = $this->request(array(
33 | 'method' => 'POST',
34 | 'requestUrl' => 'push',
35 | 'data' => array(
36 | 'channel' => '',
37 | 'data' => array(
38 | 'alert' => $this->_globalMsg
39 | )
40 | ),
41 | ));
42 | return $request;
43 |
44 | }
45 | else{
46 | if(count($this->data) > 0){
47 | if($this->channel == '' && empty($this->channels)){
48 | $this->throwError('No push channel has been set');
49 | }
50 | $params = array(
51 | 'method' => 'POST',
52 | 'requestUrl' => 'push',
53 | 'data' => array(
54 | 'data' => $this->data
55 | )
56 | );
57 |
58 | if(!empty($this->channels)){
59 | $params['data']['channels'] = $this->channels;
60 | }
61 | if(!empty($this->channel)){
62 | $params['data']['channel'] = $this->channel;
63 | }
64 | if(!empty($this->expiration_time)){
65 | $params['data']['expiration_time'] = $this->expiration_time;
66 | }
67 | if(!empty($this->expiration_time_interval)){
68 | $params['data']['expiration_interval'] = $this->expiration_interval;
69 | }
70 | if(!empty($this->content_available)){
71 | //changed back to content-available... underscores are much easier to deal with in PHP
72 | $params['data']['content-available'] = $this->content_available;
73 | }
74 | if(!empty($this->type)){
75 | $params['data']['type'] = $this->type;
76 | }
77 |
78 | $request = $this->request($params);
79 | return $request;
80 |
81 | }
82 | else{
83 | $this->throwError('No push data has been set, you must set at least data. Please see the docs. ');
84 | }
85 | }
86 | }
87 | }
88 |
89 | ?>
--------------------------------------------------------------------------------
/includes/class-wp-parse-api-admin-settings.php:
--------------------------------------------------------------------------------
1 | $numberposts,
36 | 'offset' => ($_GET['wp-parse-api-page'] * $numberposts) - $numberposts,
37 | );
38 |
39 | $wp_posts = get_posts($options);
40 |
41 | if (count($wp_posts) == 0) {
42 | wp_redirect( 'options-general.php?page=wp-parse-api-options' );
43 | exit;
44 | }
45 |
46 | foreach ($wp_posts as $wp) {
47 | if ($wp->post_status != 'publish') continue;
48 |
49 | $post = WpParseApiHelpers::postToObject($wp->ID);
50 | $q = new parseQuery(WP_PARSE_API_OBJECT_NAME);
51 | $q->whereEqualTo('wpId', $wp->ID);
52 | $q->setLimit(1);
53 | $result = $q->find();
54 |
55 | if ($result->results[0]) {
56 | $post->update($result->results[0]->objectId);
57 | } else {
58 | $post->save();
59 | }
60 | }
61 |
62 | ++$_GET['wp-parse-api-page'];
63 | $url = $_SERVER['PHP_SELF'];
64 |
65 | foreach ($_GET as $k=>$v):
66 | $qs = (strpos($url, '?') === false ? '?' : '&');
67 | $url .= sprintf("%s%s=%s", $qs, $k, $v);
68 | endforeach;
69 |
70 | //wp_redirect( $url );
71 | echo "Page:". ($_GET['wp-parse-api-page']-1) ."";
72 | exit;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/includes/class-wp-parse-api-helpers.php:
--------------------------------------------------------------------------------
1 | array(), // Default
6 | 'es' => array(
7 | 'Jan' => 'Ene',
8 | 'Apr' => 'Abr',
9 | 'Aug' => 'Ago',
10 | 'Dec' => 'Dic'
11 | )
12 | );
13 |
14 | static public function postToObject($post_id) {
15 | // Get the post
16 | $wp_post = get_post($post_id);
17 | // Init the parse object
18 | $post = new parseObject(WP_PARSE_API_OBJECT_NAME);
19 | // Get the categories
20 | $_categories = get_the_category($post_id);
21 |
22 | // Initializing vars
23 | $categories = array();
24 | $photos = array();
25 | $videos = array();
26 |
27 | // Add the categories
28 | foreach ($_categories as $row) {
29 | $categories[] = $row->name;
30 | }
31 |
32 | // Set the date in spanish format
33 | $keys = array_keys(self::$lang);
34 | $lang = self::$lang[in_array(get_option('lang'), $keys) ? get_option('lang') : $keys[0]];
35 | $date = strtr(date("d/M/Y", strtotime($wp_post->post_date)), $lang);
36 |
37 | // Add the thumbnails
38 | $thumbnails = array(
39 | 'thumbnail' => wp_get_attachment_image_src( get_post_thumbnail_id( $post_id ), 'thumbnail' ),
40 | 'medium' => wp_get_attachment_image_src( get_post_thumbnail_id( $post_id ), 'medium' ),
41 | 'large' => wp_get_attachment_image_src( get_post_thumbnail_id( $post_id ), 'large' ),
42 | 'full' => wp_get_attachment_image_src( get_post_thumbnail_id( $post_id ), 'full' )
43 | );
44 |
45 | foreach ($thumbnails as $k=>$v):
46 | if (!is_array($v)) unset($thumbnails[$k]);
47 | else $thumbnails[$k] = array_shift($v);
48 | endforeach;
49 |
50 | if (count($thumbnails) == 0) $thumbnails = new stdClass();
51 |
52 | // Extract the photos from the content
53 | preg_match_all('/
]+src=[\'"]([^\'"]+)[\'"].*>/i', $wp_post->post_content, $photos);
54 |
55 | // Extract the youtube video id's from the content
56 | $urls = array('#http://www.youtube.com/embed/([A-Za-z0-9\-_]+)#s', '#http://www.youtube.com/watch?v=([A-Za-z0-9\-_]+)#s');
57 |
58 | foreach ($urls as $url) :
59 | $tmp = array();
60 | preg_match_all($url, $wp_post->post_content, $tmp);
61 | foreach ($tmp[1] as $v) :
62 | if (!in_array($v, $videos)) $videos[] = $v;
63 | endforeach;
64 | endforeach;
65 |
66 | // Remove unwanted strings from contents
67 | $content = preg_replace('/\[.*?\](.+?)\[\/.*?\]/is', '', $wp_post->post_content);
68 | $content = strtr($content, array('
'=>''));
69 | // $content = strip_tags($content, "
");
70 | $content = explode('', $content);
71 | $content[0] = strip_tags($content[0]);
72 | $content = implode('', $content);
73 |
74 | // Set the post properties
75 | $post->categories = $categories;
76 | $post->content = $content;
77 | $post->date = $date;
78 | $post->guid = $wp_post->guid;
79 | $post->photos = $photos[1];
80 | $post->thumbnail = $thumbnails;
81 | $post->title = $wp_post->post_title;
82 | $post->videos = $videos;
83 | $post->wpId = (int)$post_id;
84 |
85 | // Return the post
86 | return $post;
87 | }
88 |
89 | public static function log($message) {
90 | if (!defined('LOG')) return;
91 | file_put_contents(LOG, "{$message}\n", FILE_APPEND);
92 | }
93 | }
--------------------------------------------------------------------------------
/includes/class-wp-parse-api-admin-settings-template.php:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
Parse Api
11 |
12 |
Register your app on parse.com then complete this form with the information about your app.
13 |
14 |
94 |
95 |
104 |
105 |
--------------------------------------------------------------------------------
/libs/parse.com-php-library/parseUser.php:
--------------------------------------------------------------------------------
1 | data[$name] = $value;
8 | }
9 |
10 | public function signup($username='',$password=''){
11 | if($username != '' && $password != ''){
12 | $this->username = $username;
13 | $this->password = $password;
14 | }
15 |
16 | if($this->data['username'] != '' && $this->data['password'] != ''){
17 | $request = $this->request(array(
18 | 'method' => 'POST',
19 | 'requestUrl' => 'users',
20 | 'data' => $this->data
21 | ));
22 |
23 | return $request;
24 |
25 | }
26 | else{
27 | $this->throwError('username and password fields are required for the signup method');
28 | }
29 |
30 | }
31 |
32 | public function login(){
33 | if(!empty($this->data['username']) || !empty($this->data['password']) ){
34 | $request = $this->request(array(
35 | 'method' => 'GET',
36 | 'requestUrl' => 'login',
37 | 'data' => array(
38 | 'password' => $this->data['password'],
39 | 'username' => $this->data['username']
40 | )
41 | ));
42 |
43 | return $request;
44 |
45 | }
46 | else{
47 | $this->throwError('username and password field are required for the login method');
48 | }
49 |
50 | }
51 |
52 | public function get($objectId){
53 | if($objectId != ''){
54 | $request = $this->request(array(
55 | 'method' => 'GET',
56 | 'requestUrl' => 'users/'.$objectId,
57 | ));
58 |
59 | return $request;
60 |
61 | }
62 | else{
63 | $this->throwError('objectId is required for the get method');
64 | }
65 |
66 | }
67 | //TODO: should make the parseUser contruct accept the objectId and update and delete would only require the sessionToken
68 | public function update($objectId,$sessionToken){
69 | if(!empty($objectId) || !empty($sessionToken)){
70 | $request = $this->request(array(
71 | 'method' => 'PUT',
72 | 'requestUrl' => 'users/'.$objectId,
73 | 'sessionToken' => $sessionToken,
74 | 'data' => $this->data
75 | ));
76 |
77 | return $request;
78 | }
79 | else{
80 | $this->throwError('objectId and sessionToken are required for the update method');
81 | }
82 |
83 | }
84 |
85 | public function delete($objectId,$sessionToken){
86 | if(!empty($objectId) || !empty($sessionToken)){
87 | $request = $this->request(array(
88 | 'method' => 'DELETE',
89 | 'requestUrl' => 'users/'.$objectId,
90 | 'sessionToken' => $sessionToken
91 | ));
92 |
93 | return $request;
94 | }
95 | else{
96 | $this->throwError('objectId and sessionToken are required for the delete method');
97 | }
98 |
99 | }
100 |
101 | public function addAuthData($authArray){
102 | if(is_array($authArray)){
103 | $this->authData[$authArray['type']] = $authArray['authData'];
104 | }
105 | else{
106 | $this->throwError('authArray must be an array containing a type key and a authData key in the addAuthData method');
107 | }
108 | }
109 |
110 | public function linkAccounts($objectId,$sessionToken){
111 | if(!empty($objectId) || !empty($sessionToken)){
112 | $request = $this->request( array(
113 | 'method' => 'PUT',
114 | 'requestUrl' => 'users/'.$objectId,
115 | 'sessionToken' => $sessionToken,
116 | 'data' => array(
117 | 'authData' => $this->authData
118 | )
119 | ));
120 |
121 | return $request;
122 | }
123 | else{
124 | $this->throwError('objectId and sessionToken are required for the linkAccounts method');
125 | }
126 | }
127 |
128 | public function unlinkAccount($objectId,$sessionToken,$type){
129 | $linkedAccount[$type] = null;
130 |
131 | if(!empty($objectId) || !empty($sessionToken)){
132 | $request = $this->request( array(
133 | 'method' => 'PUT',
134 | 'requestUrl' => 'users/'.$objectId,
135 | 'sessionToken' => $sessionToken,
136 | 'data' => array(
137 | 'authData' => $linkedAccount
138 | )
139 | ));
140 |
141 | return $request;
142 | }
143 | else{
144 | $this->throwError('objectId and sessionToken are required for the linkAccounts method');
145 | }
146 |
147 | }
148 |
149 | public function requestPasswordReset($email){
150 | if(!empty($email)){
151 | $this->email - $email;
152 | $request = $this->request(array(
153 | 'method' => 'POST',
154 | 'requestUrl' => 'requestPasswordReset',
155 | 'email' => $email,
156 | 'data' => $this->data
157 | ));
158 |
159 | return $request;
160 | }
161 | else{
162 | $this->throwError('email is required for the requestPasswordReset method');
163 | }
164 |
165 | }
166 |
167 |
168 | }
169 |
170 | ?>
--------------------------------------------------------------------------------
/wp-parse-api.php:
--------------------------------------------------------------------------------
1 | option_name . '_nonce' ], $this->action)) return;
90 | // WpParseApiHelpers::log("WpParseApi::save_post($post_id) | nonce passed");
91 | // Verify post status
92 | if (get_post_status($post_id) != 'publish') return;
93 | WpParseApiHelpers::log("WpParseApi::save_post($post_id) | status passed");
94 |
95 | $post = WpParseApiHelpers::postToObject($post_id);
96 |
97 | // Creates a new post on parse.com
98 | if (!get_post_meta($post_id, 'wp_parse_api_code_run', true)) {
99 | update_post_meta($post_id, 'wp_parse_api_code_run', true);
100 |
101 | $categories = array();
102 |
103 | foreach ($post->data['categories'] as $row) {
104 | $row = trim(preg_replace('/[^a-zA-Z]/', '', $row));
105 | if ($row != '') $categories[] = $row;
106 | }
107 |
108 | // Check if there is no categories or push notifications are disabled
109 | if (is_array($categories) && count($categories) > 0 && get_option('app_push_notifications') != 'Off') {
110 | try {
111 | $push = new parsePush();
112 | $push->alert = $post->data['title'];
113 | $push->channels = $categories;
114 | $push->badge = "increment";
115 | $push->sound = "example.caf";
116 | $push->post_id = $post->data[wpId];
117 | $push->url = $post->data['guid'];
118 | $push->category = "ACTIONABLE";
119 | $push->send(); }
120 | catch (Exception $e) {
121 | // do nothing, this was added because
122 | // parse lib throws an exception if the account
123 | // has not been configured
124 | // special thanks to raymondmuller for find the issue
125 | }
126 | }
127 |
128 | $post->save();
129 | // Update an existin post on parse.com
130 | } else {
131 | $q = new parseQuery(WP_PARSE_API_OBJECT_NAME);
132 | $q->where('wpId', (int)$post_id);
133 | $r = $q->find();
134 |
135 | if (is_array($r->results)) $r = array_shift($r->results);
136 | if ($r != null) $post->update($r->objectId);
137 | }
138 |
139 | WpParseApiHelpers::log("WpParseApi::save_post($post_id) | END");
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | ## Parse its shutting down their BaaS, but they open sourced it at [parse-server](https://github.com/ParsePlatform/parse-server), please consider this before try to use this plugin, b/c its not prepared for use outside parse, it can be used but need to point all the endpoints urls to your own parse server
2 |
3 | Also I'm not maintaining anymore this plugin, you can fork it and make your changes or submit al pullrequest
4 |
5 | # WordPress Parse Api
6 |
7 | [](https://gitter.im/norman784/wp-parse-api?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
8 |
9 | Bridge between [Parse](http://parse.com) api and [WordPress](http://wordpress.org)
10 |
11 | ## Description
12 |
13 | The goal of this plugin its to replicate all your posts to [Parse](http://parse.com) so you can easily
14 | develop mobile apps, because I find very useful their SDK and help us to develop
15 | apps faster without worring about the security or if someone else can read data from our blog
16 | and use it.
17 |
18 | ## Features
19 |
20 | * Post object saved (create/update) to [Parse](http://parse.com)
21 | * Push notifications when new post published
22 | * Turn on/off push notifications when new post published
23 | * Sync old post to [Parse](http://parse.com)
24 | * Plugin can be updated from github, thanks to [WordPress Github Plugin Updater](https://github.com/jkudish/WordPress-GitHub-Plugin-Updater)
25 |
26 | ## Installation
27 |
28 | 1. Create your account on [Parse](http://parse.com)
29 | 2. Create an app
30 | 3. Create an class in the data browser with those fields:
31 | * categories (Array)
32 | * content (String)
33 | * date (String)
34 | * guid (String)
35 | * photos (Array)
36 | * thumbnail (Object)
37 | * title (String)
38 | * videos (Array)
39 | * wpId (Number)
40 | 4. Upload `wp-parse-api` to the `/wp-content/plugins/` directory
41 | 5. Activate the plugin through the 'Plugins' menu in WordPress
42 | 6. Go to Settings -> Parse Api
43 | 7. Fill the form with the data from your Parse.com app dashboard
44 | 8. At this point it must be ready to use it
45 |
46 | ## Frequently Asked Questions
47 |
48 | ### Why Parse.com?
49 |
50 | Because I find there a well documented SDK's for the most popular mobile platforms.
51 |
52 | ### How it works?
53 |
54 | Configure the plugin under Settings -> Parse Api as describe in the instalation.
55 | Every time you publish or save a published post it will create/update their
56 | respective row on [Parse](http://parse.com)
57 |
58 | Then use the SDK of your prefered platform and start coding.
59 |
60 | ## TODO
61 |
62 | * Better way to handle synchronization (don't research so much if wp has a build in cronjob)
63 | * Prepare for submit into the wordpress plugin repository
64 | * Built a log event registry and visualization
65 | * Add test case files
66 |
67 | ## Changelog
68 |
69 | **0.5.1**
70 | * Check that the app url ends with `/`, if not we add it
71 |
72 | **0.5.0**
73 | * Added date internationalization support (English, Español)
74 | * Bug fixes
75 |
76 | **0.4.1**
77 | * Bug fixes
78 |
79 | **0.4**
80 | * Added support for youtube videos
81 | * Added some comments on the source code
82 |
83 | **0.3.1**
84 | * Fixed bug that send push notification if category is null or an empty string, seems that my previous fixes not work :(
85 |
86 | **0.3.0**
87 | * Added an option to turn on/off push notifications
88 | * Added github plugin updater
89 |
90 | **0.2.9**
91 | * Fix issue if no push certificate or valid push certificate was configured (thanks to raymondmuller)
92 |
93 | **0.2.8**
94 | * Small improvement, if categories are empty no push notification will be send
95 |
96 | **0.2.7**
97 | * Fix push notifications, now it get the categories from the post
98 |
99 | **0.2.6**
100 | * Fix to remove the bbcode and their content
101 |
102 | **0.2.5**
103 | * Fix sync, now update/insert works
104 | * Added log helper
105 |
106 | **0.2.4**
107 | * Fix sync, now update/insert works
108 | * Fix img src isolation
109 | * Changed limit per page from 20 to 10
110 |
111 | **0.2.3**
112 | * Fix sync, now the pagination works fine
113 | * Now refresh via javascript, instead of php wp_rediect to prevent browser error "too many redirections"
114 | * Changed sort tag php with full php tag
115 |
116 | **0.2.2**
117 | * Added guid and photos fields
118 | * Embed photos in the content field will be extracted and pushed on photos field
119 | * Strip all html tags from the intro content
120 | * Strip certain html tags from the extended content
121 |
122 | **0.2.1**
123 | * Fix: now sync all posts instead of the first 5
124 |
125 | **0.2**
126 | * Add a fix for the 3rd party class parseRestClient to get to work in php < 5.3
127 | * Readme: changed thumbnail type to Object
128 | * Fixed thumbnails tag img was returned before the fix, now returns the url
129 | * In wp-parse-api.php changed functions to class
130 |
131 | **0.1**
132 | Initial Commit
133 |
134 | ## About
135 |
136 | Contributors: normanpaniagua
137 |
138 | Tags: parse.com, api
139 |
140 | Requires at least: 3.0.1 (not tested)
141 |
142 | Tested up to: 3.5
143 |
144 | License: GPLv2 or later
145 |
146 | License URI: http://www.gnu.org/licenses/gpl-2.0.html
147 |
--------------------------------------------------------------------------------
/libs/parse.com-php-library/parse.php:
--------------------------------------------------------------------------------
1 | _appid = $parseConfig->APPID;
27 | $this->_masterkey = $parseConfig->MASTERKEY;
28 | $this->_restkey = $parseConfig->RESTKEY;
29 | $this->_parseurl = $parseConfig->PARSEURL;
30 |
31 | if(empty($this->_appid) || empty($this->_restkey) || empty($this->_masterkey)){
32 | $this->throwError('You must set your Application ID, Master Key and REST API Key');
33 | }
34 |
35 | $version = curl_version();
36 | $ssl_supported = ( $version['features'] & CURL_VERSION_SSL );
37 |
38 | if(!$ssl_supported){
39 | $this->throwError('CURL ssl support not found');
40 | }
41 |
42 | }
43 |
44 | /*
45 | * All requests go through this function
46 | *
47 | *
48 | */
49 | public function request($args){
50 | $isFile = false;
51 | $c = curl_init();
52 | curl_setopt($c, CURLOPT_TIMEOUT, 30);
53 | curl_setopt($c, CURLOPT_USERAGENT, 'parse.com-php-library/2.0');
54 | curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
55 | curl_setopt($c, CURLINFO_HEADER_OUT, true);
56 | if(substr($args['requestUrl'],0,5) == 'files'){
57 | curl_setopt($c, CURLOPT_HTTPHEADER, array(
58 | 'Content-Type: '.$args['contentType'],
59 | 'X-Parse-Application-Id: '.$this->_appid,
60 | 'X-Parse-Master-Key: '.$this->_masterkey
61 | ));
62 | $isFile = true;
63 | }
64 | else if(substr($args['requestUrl'],0,5) == 'users' && isset($args['sessionToken'])){
65 | curl_setopt($c, CURLOPT_HTTPHEADER, array(
66 | 'Content-Type: application/json',
67 | 'X-Parse-Application-Id: '.$this->_appid,
68 | 'X-Parse-REST-API-Key: '.$this->_restkey,
69 | 'X-Parse-Session-Token: '.$args['sessionToken']
70 | ));
71 | }
72 | else{
73 | curl_setopt($c, CURLOPT_HTTPHEADER, array(
74 | 'Content-Type: application/json',
75 | 'X-Parse-Application-Id: '.$this->_appid,
76 | 'X-Parse-REST-API-Key: '.$this->_restkey,
77 | 'X-Parse-Master-Key: '.$this->_masterkey
78 | ));
79 | }
80 | curl_setopt($c, CURLOPT_CUSTOMREQUEST, $args['method']);
81 | $url = $this->_parseurl . $args['requestUrl'];
82 |
83 | if($args['method'] == 'PUT' || $args['method'] == 'POST'){
84 | if($isFile){
85 | $postData = $args['data'];
86 | }
87 | else{
88 | $postData = json_encode($args['data']);
89 | }
90 |
91 | curl_setopt($c, CURLOPT_POSTFIELDS, $postData );
92 | }
93 |
94 | if($args['requestUrl'] == 'login'){
95 | $urlParams = http_build_query($args['data'], '', '&');
96 | $url = $url.'?'.$urlParams;
97 | }
98 | if(array_key_exists('urlParams',$args)){
99 | $urlParams = http_build_query($args['urlParams'], '', '&');
100 | $url = $url.'?'.$urlParams;
101 | }
102 |
103 | curl_setopt($c, CURLOPT_URL, $url);
104 |
105 | $response = curl_exec($c);
106 | $responseCode = curl_getinfo($c, CURLINFO_HTTP_CODE);
107 |
108 | $expectedCode = '200';
109 | if($args['method'] == 'POST' && substr($args['requestUrl'],0,4) != 'push'){
110 | $expectedCode = '201';
111 | }
112 |
113 | if($expectedCode != $responseCode){
114 | //BELOW HELPS WITH DEBUGGING
115 | //print_r($response);
116 | //print_r($args);
117 | }
118 |
119 | return $this->checkResponse($response,$responseCode,$expectedCode);
120 | }
121 |
122 | public function dataType($type,$params){
123 | if($type != ''){
124 | switch($type){
125 | case 'date':
126 | $return = array(
127 | "__type" => "Date",
128 | "iso" => date("c", strtotime($params))
129 | );
130 | break;
131 | case 'bytes':
132 | $return = array(
133 | "__type" => "Bytes",
134 | "base64" => base64_encode($params)
135 | );
136 | break;
137 | case 'pointer':
138 | $return = array(
139 | "__type" => "Pointer",
140 | "className" => $params[0],
141 | "objectId" => $params[1]
142 | );
143 | break;
144 | case 'geopoint':
145 | $return = array(
146 | "__type" => "GeoPoint",
147 | "latitude" => floatval($params[0]),
148 | "longitude" => floatval($params[1])
149 | );
150 | break;
151 | case 'file':
152 | $return = array(
153 | "__type" => "File",
154 | "name" => $params[0],
155 | );
156 | break;
157 | case 'increment':
158 | $return = array(
159 | "__op" => "Increment",
160 | "amount" => $params[0]
161 | );
162 | break;
163 | case 'decrement':
164 | $return = array(
165 | "__op" => "Decrement",
166 | "amount" => $params[0]
167 | );
168 | break;
169 | default:
170 | $return = false;
171 | break;
172 | }
173 |
174 | return $return;
175 | }
176 | }
177 |
178 | public function throwError($msg,$code=0){
179 | throw new ParseLibraryException($msg,$code);
180 | }
181 |
182 | private function checkResponse($response,$responseCode,$expectedCode){
183 | //TODO: Need to also check for response for a correct result from parse.com
184 | if($responseCode != $expectedCode){
185 | $error = json_decode($response);
186 | $this->throwError($error->error,$error->code);
187 | }
188 | else{
189 | //check for empty return
190 | if($response == '{}'){
191 | return true;
192 | }
193 | else{
194 | return json_decode($response);
195 | }
196 | }
197 | }
198 | }
199 |
200 |
201 | class ParseLibraryException extends Exception{
202 | public function __construct($message, $code = 0, Exception $previous = null) {
203 | //codes are only set by a parse.com error
204 | if($code != 0){
205 | $message = "parse.com error: ".$message;
206 | }
207 |
208 | parent::__construct($message, $code, $previous);
209 | }
210 |
211 | public function __toString() {
212 | return __CLASS__ . ": [{$this->code}]: {$this->message}\n";
213 | }
214 |
215 | }
216 |
217 | ?>
--------------------------------------------------------------------------------
/libs/parse.com-php-library/parseQuery.php:
--------------------------------------------------------------------------------
1 | _requestUrl = $class;
14 | }
15 | elseif($class != ''){
16 | $this->_requestUrl = 'classes/'.$class;
17 | }
18 | else{
19 | $this->throwError('include the className when creating a parseQuery');
20 | }
21 |
22 | parent::__construct();
23 |
24 | }
25 |
26 | public function find(){
27 | if(empty($this->_query)){
28 | $this->throwError('No query set yet.');
29 | }
30 | else{
31 | $urlParams = array(
32 | 'where' => json_encode( $this->_query )
33 | );
34 | if(!empty($this->_include)){
35 | $urlParams['include'] = implode(',',$this->_include);
36 | }
37 | if(!empty($this->_order)){
38 | $urlParams['order'] = implode(',',$this->_order);
39 | }
40 | if(!empty($this->_limit)){
41 | $urlParams['limit'] = $this->_limit;
42 | }
43 | if(!empty($this->_skip)){
44 | $urlParams['skip'] = $this->_skip;
45 | }
46 | if($this->_count == 1){
47 | $urlParams['count'] = '1';
48 | $urlParams['limit'] = '0';
49 | }
50 |
51 | $request = $this->request(array(
52 | 'method' => 'GET',
53 | 'requestUrl' => $this->_requestUrl,
54 | 'urlParams' => $urlParams,
55 | ));
56 |
57 | return $request;
58 | }
59 | }
60 |
61 | public function getCount(){
62 | $this->_count = 1;
63 | $this->_limit = 0;
64 | return $this->find();
65 | }
66 |
67 | public function setLimit($int){
68 | if ($int >= 1 && $int <= 1000){
69 | $this->_limit = $int;
70 | }
71 | else{
72 | $this->throwError('parse requires the limit parameter be between 1 and 1000');
73 | }
74 | }
75 |
76 | public function setSkip($int){
77 | $this->_skip = $int;
78 | }
79 |
80 | public function orderBy($field){
81 | if(!empty($field)){
82 | $this->_order[] = $field;
83 | }
84 | }
85 |
86 | public function orderByAscending($value){
87 | if(is_string($value)){
88 | $this->_order[] = $value;
89 | }
90 | else{
91 | $this->throwError('the order parameter on a query must be a string');
92 | }
93 | }
94 |
95 | public function orderByDescending($value){
96 | if(is_string($value)){
97 | $this->_order[] = '-'.$value;
98 | }
99 | else{
100 | $this->throwError('the order parameter on parseQuery must be a string');
101 | }
102 | }
103 |
104 | public function whereInclude($value){
105 | if(is_string($value)){
106 | $this->_include[] = $value;
107 | }
108 | else{
109 | $this->throwError('the include parameter on parseQuery must be a string');
110 | }
111 | }
112 |
113 | public function where($key,$value){
114 | $this->whereEqualTo($key,$value);
115 | }
116 |
117 | public function whereEqualTo($key,$value){
118 | if(isset($key) && isset($value)){
119 | $this->_query[$key] = $value;
120 | }
121 | else{
122 | $this->throwError('the $key and $value parameters must be set when setting a "where" query method');
123 | }
124 | }
125 |
126 | public function whereNotEqualTo($key,$value){
127 | if(isset($key) && isset($value)){
128 | $this->_query[$key] = array(
129 | '$ne' => $value
130 | );
131 | }
132 | else{
133 | $this->throwError('the $key and $value parameters must be set when setting a "where" query method');
134 | }
135 | }
136 |
137 | public function whereGreaterThan($key,$value){
138 | if(isset($key) && isset($value)){
139 | $this->_query[$key] = array(
140 | '$gt' => $value
141 | );
142 | }
143 | else{
144 | $this->throwError('the $key and $value parameters must be set when setting a "where" query method');
145 | }
146 |
147 | }
148 |
149 | public function whereLessThan($key,$value){
150 | if(isset($key) && isset($value)){
151 | $this->_query[$key] = array(
152 | '$lt' => $value
153 | );
154 | }
155 | else{
156 | $this->throwError('the $key and $value parameters must be set when setting a "where" query method');
157 | }
158 |
159 | }
160 |
161 | public function whereGreaterThanOrEqualTo($key,$value){
162 | if(isset($key) && isset($value)){
163 | $this->_query[$key] = array(
164 | '$gte' => $value
165 | );
166 | }
167 | else{
168 | $this->throwError('the $key and $value parameters must be set when setting a "where" query method');
169 | }
170 |
171 | }
172 |
173 | public function whereLessThanOrEqualTo($key,$value){
174 | if(isset($key) && isset($value)){
175 | $this->_query[$key] = array(
176 | '$lte' => $value
177 | );
178 | }
179 | else{
180 | $this->throwError('the $key and $value parameters must be set when setting a "where" query method');
181 | }
182 |
183 | }
184 |
185 | public function whereContainedIn($key,$value){
186 | if(isset($key) && isset($value)){
187 | if(is_array($value)){
188 | $this->_query[$key] = array(
189 | '$in' => $value
190 | );
191 | }
192 | else{
193 | $this->throwError('$value must be an array to check through');
194 | }
195 | }
196 | else{
197 | $this->throwError('the $key and $value parameters must be set when setting a "where" query method');
198 | }
199 |
200 | }
201 |
202 | public function whereNotContainedIn($key,$value){
203 | if(isset($key) && isset($value)){
204 | if(is_array($value)){
205 | $this->_query[$key] = array(
206 | '$nin' => $value
207 | );
208 | }
209 | else{
210 | $this->throwError('$value must be an array to check through');
211 | }
212 | }
213 | else{
214 | $this->throwError('the $key and $value parameters must be set when setting a "where" query method');
215 | }
216 |
217 | }
218 |
219 | public function whereExists($key){
220 | if(isset($key)){
221 | $this->_query[$key] = array(
222 | '$exists' => true
223 | );
224 | }
225 | }
226 |
227 | public function whereDoesNotExist($key){
228 | if(isset($key)){
229 | $this->_query[$key] = array(
230 | '$exists' => false
231 | );
232 | }
233 | }
234 |
235 | public function whereRegex($key,$value,$options=''){
236 | if(isset($key) && isset($value)){
237 | $this->_query[$key] = array(
238 | '$regex' => $value
239 | );
240 |
241 | if(!empty($options)){
242 | $this->_query[$key]['options'] = $options;
243 | }
244 | }
245 | else{
246 | $this->throwError('the $key and $value parameters must be set when setting a "where" query method');
247 | }
248 |
249 | }
250 |
251 | public function wherePointer($key,$className,$objectId){
252 | if(isset($key) && isset($className)){
253 | $this->_query[$key] = $this->dataType('pointer', array($className,$objectId));
254 | }
255 | else{
256 | $this->throwError('the $key and $className parameters must be set when setting a "where" pointer query method');
257 | }
258 |
259 | }
260 |
261 | public function whereInQuery($key,$className,$inQuery){
262 | if(isset($key) && isset($className)){
263 | $this->_query[$key] = array(
264 | '$inQuery' => $inQuery,
265 | 'className' => $className
266 | );
267 | }
268 | else{
269 | $this->throwError('the $key and $value parameters must be set when setting a "where" query method');
270 | }
271 |
272 | }
273 |
274 | public function whereNotInQuery($key,$className,$inQuery){
275 | if(isset($key) && isset($className)){
276 | $this->_query[$key] = array(
277 | '$notInQuery' => $inQuery,
278 | 'className' => $className
279 | );
280 | }
281 | else{
282 | $this->throwError('the $key and $value parameters must be set when setting a "where" query method');
283 | }
284 |
285 | }
286 | }
287 |
288 | ?>
--------------------------------------------------------------------------------