Skip to content

Commit a5e8c9f

Browse files
committed
Finished first production-ready release.
Added dependency checking upon activation. Implemented language filter and fixed problems with WPML modifying post queries by default. Added support for tags and translation of categories and tags. Finished first complete draft of the readme.
1 parent 85ff662 commit a5e8c9f

File tree

6 files changed

+307
-21
lines changed

6 files changed

+307
-21
lines changed

lib/wpml_json_api.php

Lines changed: 92 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
require_once WPML_JSON_API_PATH.'/models/translation.php';
55

66
class WPML_JSON_API {
7+
protected $plugin_path;
8+
79
/**
810
* @var JSON_API
911
*/
@@ -14,12 +16,33 @@ class WPML_JSON_API {
1416
*/
1517
private $_sp;
1618

19+
/**
20+
* Constructs a new api for the specified plugin.
21+
*/
22+
function __construct($plugin_path) {
23+
if (strpos($plugin_path, WP_PLUGIN_DIR) === 0) {
24+
$this->plugin_path = ltrim(substr($plugin_path, strlen(WP_PLUGIN_DIR)), DIRECTORY_SEPARATOR);
25+
}
26+
else {
27+
$this->plugin_path = $plugin_path;
28+
}
29+
}
30+
1731
/**
1832
* Registers all filters and actions.
1933
*/
2034
function register() {
21-
add_filter('json_api_encode', array($this, 'dispatch_translate_resource_filter'));
35+
// Trick WPML by hardcoding the 'lang' GET parameter. Otherwise, it will
36+
// rewrite post queries to only return those in the default language. This
37+
// would interfere with the retrieval of explicitly requested JSON-API
38+
// objects.
39+
$_GET['lang'] = 'all';
40+
2241
add_filter('json_api_encode', array($this, 'dispatch_add_translations_filter'));
42+
add_filter('json_api_encode', array($this, 'dispatch_filter_for_language_filter'));
43+
add_filter('json_api_encode', array($this, 'dispatch_translate_resource_filter'));
44+
45+
add_action('activate_'.$this->plugin_path, array($this, 'ensure_plugin_dependencies'));
2346
}
2447

2548
/**
@@ -34,15 +57,17 @@ function dispatch_filter($filter, $arguments) {
3457
$error = null;
3558

3659
// Resolve the object to filter and filter it.
37-
foreach ($response as $type => $value) {
38-
if (is_object($value)) {
39-
$resources = array($value);
60+
foreach (array_keys($response) as $type) {
61+
if (is_object($response[$type])) {
62+
$resources = array($response[$type]);
4063
$error = $this->$filter($type, $resources);
4164
break;
4265
}
43-
elseif (is_array($value) && is_object($value[0])) {
44-
$error = $this->$filter($type, $value);
45-
break;
66+
elseif (is_array($response[$type]) && isset($response[$type][0])) {
67+
if (is_object($response[$type][0])) {
68+
$error = $this->$filter($type, $response[$type]);
69+
break;
70+
}
4671
}
4772
}
4873

@@ -53,6 +78,28 @@ function dispatch_filter($filter, $arguments) {
5378
return $response;
5479
}
5580

81+
/**
82+
* Ensures that the plugin dependencies are fulfilled. If the WPML plugin is
83+
* enabled network wide than this plugin must be as well.
84+
*/
85+
function ensure_plugin_dependencies($network_wide) {
86+
if (!is_plugin_active('json-api/json-api.php')) {
87+
trigger_error('This plugin requires JSON-API!', E_USER_ERROR);
88+
}
89+
90+
if (!is_plugin_active('sitepress-multilingual-cms/sitepress.php')) {
91+
trigger_error('This plugin requires WPML Multilingual CMS!', E_USER_ERROR);
92+
}
93+
elseif (!$network_wide) {
94+
$plugins = get_site_option('active_sitewide_plugins', array(), false);
95+
if (is_plugin_active_for_network('sitepress-multilingual-cms/sitepress.php')) {
96+
trigger_error(
97+
'WPML Multilingual CMS is enabled network wide. '.
98+
'You must enable this plugin network wide as well.', E_USER_ERROR);
99+
}
100+
}
101+
}
102+
56103
/**
57104
* Returns the requested query parameter value.
58105
*
@@ -86,6 +133,37 @@ function language_is_supported($language_code) {
86133
return false;
87134
}
88135

136+
/**
137+
* Filters the response resources to only include those for the specified
138+
* language.
139+
*/
140+
function filter_for_language($type, &$resources) {
141+
$numeric_keys = false;
142+
$modified = false;
143+
144+
foreach (array_keys($resources) as $k) {
145+
$numeric_keys = is_numeric($k);
146+
147+
if (($language = $this->json->query->language) && isset($resources[$k]->language)) {
148+
if ($this->language_is_supported($language)) {
149+
if ($language != 'all' && $language != $resources[$k]->language) {
150+
unset($resources[$k]);
151+
$modified = true;
152+
}
153+
}
154+
else {
155+
return array('status' => 'error', 'error' => 'Language not supported.');
156+
}
157+
}
158+
}
159+
160+
// If array has numeric keys and we deleted something, we have to reset
161+
// the key order so it will be properly JSON encoded as an array.
162+
if ($modified && $numeric_keys) {
163+
$resources = array_values($resources);
164+
}
165+
}
166+
89167
/**
90168
* Augments the response resource with the languages and translations.
91169
*/
@@ -112,11 +190,11 @@ function add_translations($type, &$resources) {
112190
* available.
113191
*/
114192
function translate_resource($type, &$resources) {
115-
if ($to_lang = $this->get_param('to_lang')) {
116-
if ($this->language_is_supported($to_lang)) {
193+
if ($to_language = $this->json->query->to_language) {
194+
if ($this->language_is_supported($to_language)) {
117195
foreach ($resources as $resource) {
118196
if ($wpml_resource = WPML_JSON_API_Resource::create($type, $resource)) {
119-
$wpml_resource->translate_resource($resource, $to_lang);
197+
$wpml_resource->translate_resource($resource, $to_language);
120198
}
121199
else {
122200
return array('status' => 'error', 'error' => "Type `$type' is not translatable.");
@@ -159,4 +237,8 @@ function __call($method, $arguments) {
159237
return $this->dispatch_filter($m[1], $arguments);
160238
}
161239
}
240+
241+
private function find_plugin_in($plugins, $names) {
242+
return array_search(implode(DIRECTORY_SEPARATOR, (array) $names), array_keys($plugins));
243+
}
162244
}

models/category.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
require_once WPML_JSON_API_PATH.'/models/resource.php';
44

55
class WPML_JSON_API_Category extends WPML_JSON_API_Resource {
6+
public $translatable_properties = array(
7+
'slug',
8+
'title',
9+
'description',
10+
);
611
protected $type = 'category';
712
protected $wpml_type = 'tax_category';
813
}

models/tag.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
require_once WPML_JSON_API_PATH.'/models/category.php';
4+
5+
class WPML_JSON_API_Tag extends WPML_JSON_API_Category {
6+
protected $type = 'tag';
7+
protected $wpml_type = 'tax_post_tag';
8+
}

models/tag_translation.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
require_once WPML_JSON_API_PATH.'/models/translation.php';
4+
5+
/**
6+
* A translation of a WPML_JSON_API_Tag.
7+
*/
8+
class WPML_JSON_API_TagTranslation extends WPML_JSON_API_Translation {
9+
public $name;
10+
public $term_id;
11+
public $post_count;
12+
13+
function __construct($tag, $translation) {
14+
parent::__construct($tag, $translation);
15+
16+
$this->name = $translation->name;
17+
$this->term_id = (integer) $translation->term_id;
18+
$this->post_count = (integer) $translation->instances;
19+
}
20+
21+
/**
22+
* Returns the tag for this translation.
23+
*
24+
* @return JSON_API_Tag
25+
*/
26+
function resolve_resource() {
27+
$wp_tag = get_term_by('id', $this->resource_id, 'post_tag');
28+
29+
if (!is_null($wp_tag)) {
30+
return $this->_resource = new JSON_API_Tag($wp_tag);
31+
}
32+
}
33+
34+
}

0 commit comments

Comments
 (0)