| 1 |
<?php if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly |
| 2 |
|
| 3 |
|
| 4 |
/** |
| 5 |
* Processes the Zotero request. Accepts WP AJAX or PHP calls. |
| 6 |
* |
| 7 |
* Used by: shortcode.php |
| 8 |
* |
| 9 |
* @param bol $is_ajax Whether it's an WP AJAX call. |
| 10 |
* |
| 11 |
* @return str JSON with: (a) meta about request, and (b) all data for this request. |
| 12 |
*/ |
| 13 |
function Zotpress_shortcode_request( $zpr=false, $checkcache=false ) |
| 14 |
{ |
| 15 |
$is_ajax = isset($_GET['zpShortcode_nonce']); |
| 16 |
|
| 17 |
if ( $is_ajax ) |
| 18 |
check_ajax_referer( 'zpShortcode_nonce_val', 'zpShortcode_nonce' ); |
| 19 |
|
| 20 |
// Set up database |
| 21 |
global $wpdb, $post; |
| 22 |
|
| 23 |
// Prep request vars |
| 24 |
if ( $zpr === false || $zpr == '' ) |
| 25 |
$zpr = Zotpress_prep_ajax_request_vars($wpdb); |
| 26 |
|
| 27 |
// Include relevant classes and functions |
| 28 |
include( dirname(__FILE__) . '/../request/request.class.php' ); |
| 29 |
include( dirname(__FILE__) . '/../request/request.functions.php' ); |
| 30 |
|
| 31 |
// Set up request queue (for items) |
| 32 |
// Structure: [api_user_id] => [items], [requests] |
| 33 |
$zp_request_queue = array(); |
| 34 |
|
| 35 |
// Set up Zotpress request |
| 36 |
$zp_import_contents = new ZotpressRequest(); |
| 37 |
|
| 38 |
// Set up request meta |
| 39 |
$zp_request_meta = array( "request_last" => (int) $zpr["request_last"], "request_next" => 0 ); |
| 40 |
|
| 41 |
// Set up data variable |
| 42 |
$zp_all_the_data = array(); |
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
// +---------------------------+ |
| 47 |
// | Format Zotero request URL | |
| 48 |
// +---------------------------+ |
| 49 |
|
| 50 |
// Account for items + collection_id |
| 51 |
if ( $zpr["item_type"] == "items" |
| 52 |
&& $zpr["collection_id"] !== false ) |
| 53 |
{ |
| 54 |
$zpr["item_type"] = "collections"; |
| 55 |
$zpr["sub"] = "items"; |
| 56 |
$zpr["get_top"] = false; |
| 57 |
} |
| 58 |
|
| 59 |
// Account for items + zp_tag_id |
| 60 |
if ( $zpr["item_type"] == "items" |
| 61 |
&& $zpr["tag_id"] !== false ) |
| 62 |
$zpr["get_top"] = false; |
| 63 |
|
| 64 |
// Account for collection_id + get_top |
| 65 |
if ( $zpr["get_top"] |
| 66 |
&& $zpr["collection_id"] !== false ) |
| 67 |
{ |
| 68 |
$zpr["get_top"] = false; |
| 69 |
$zpr["sub"] = "collections"; |
| 70 |
} |
| 71 |
|
| 72 |
// Account for tag display - let's limit it |
| 73 |
if ( $zpr["is_dropdown"] === true |
| 74 |
&& $zpr["item_type"] == "tags" ) |
| 75 |
{ |
| 76 |
$zpr["sortby"] = "numItems"; // title |
| 77 |
$zpr["order"] = "desc"; // asc |
| 78 |
$zpr["limit"] = 100; if ( $zpr["maxtags"] ) $zpr["limit"] = $zpr["maxtags"]; |
| 79 |
$zpr["overwrite_last_request"] = $zpr["limit"]; // QUESTION: Unsure |
| 80 |
$zpr["overwrite_request"] = true; |
| 81 |
|
| 82 |
// REVIEW: we don't want tags within a collection, |
| 83 |
// accounting for Library Dropdown browse bar (7.3.1.1) |
| 84 |
// $zpr["get_top"] = false; |
| 85 |
// $zpr["collection_id"] = false; |
| 86 |
} |
| 87 |
|
| 88 |
// Account for $zpr["maxresults"] |
| 89 |
// TODO: The Help says this is only for the searchbar .......... |
| 90 |
// TEST: Isn't this only for the library? |
| 91 |
if ( $zpr["is_dropdown"] === true |
| 92 |
&& $zpr["maxresults"] ) |
| 93 |
{ |
| 94 |
// If 50 or less, set as limit |
| 95 |
if ( (int) $zpr["maxresults"] <= 50 ) |
| 96 |
{ |
| 97 |
$zpr["limit"] = $zpr["maxresults"]; |
| 98 |
$zpr["overwrite_request"] = true; |
| 99 |
} |
| 100 |
|
| 101 |
// If over 50, then overwrite last_request |
| 102 |
else |
| 103 |
{ |
| 104 |
$zpr["overwrite_last_request"] = $zpr["maxresults"]; |
| 105 |
} |
| 106 |
} |
| 107 |
|
| 108 |
|
| 109 |
// Handle the possible formats of item/s for bib and in-text |
| 110 |
// REVIEW: Actually, removed page numbers (if any) in shortcode.intext.php |
| 111 |
// |
| 112 |
// IN-TEXT FORMATS: |
| 113 |
// [zotpressInText item="NCXAA92F"] |
| 114 |
// [zotpressInText item="{NCXAA92F}"] |
| 115 |
// [zotpressInText item="{NCXAA92F,10-15}"] |
| 116 |
// [zotpressInText items="{NCXAA92F,10-15},{55MKF89B,1578},{3ITTIXHP}"] |
| 117 |
// [zotpressInText items="{000001:NCXAA92F,10-15},{000003:3ITTIXHP}"] |
| 118 |
// [zotpressInText items="{000001:NCXAA92F,10-15},{000003:3ITTIXHP,(33,36)}"] |
| 119 |
// So no multiples without curlies or non-curlies in multiples |
| 120 |
// |
| 121 |
// BIB FORMATS: |
| 122 |
// [zotpress item="GMGCJU34"] |
| 123 |
// [zotpress items="GMGCJU34,U9Z5JTKC"] |
| 124 |
// [zotpress item="{000001:XH4BS8MA},{000001:CN73PTWE},{000003:CZR96TX9}"] |
| 125 |
// BASICALLY: Create a list of unique item keys per API User ID |
| 126 |
// REVIEW: Deal with everything!!!!!!! In the new format |
| 127 |
if ( $zpr["item_key"] |
| 128 |
&& strpos( $zpr["item_key"], ":" ) !== false ) |
| 129 |
{ |
| 130 |
$zp_items = preg_split( "/((;)|(,))+/", $zpr["item_key"] ); |
| 131 |
|
| 132 |
foreach ( $zp_items as $id => $zp_item_data ) |
| 133 |
{ |
| 134 |
$zp_item = explode( ":", substr( $zp_item_data, 1, -1 ) ); |
| 135 |
|
| 136 |
// Create items queue for API User ID, if it doesn't exist |
| 137 |
if ( ! array_key_exists( $zp_item[0], $zp_request_queue ) ) |
| 138 |
$zp_request_queue[$zp_item[0]]["items"] = ""; |
| 139 |
|
| 140 |
// Add item if not in queue |
| 141 |
if ( strpos( $zp_request_queue[$zp_item[0]]["items"], $zp_item[1] ) === false ) |
| 142 |
{ |
| 143 |
$temp_item_key = $zp_item[1]; |
| 144 |
|
| 145 |
if ( strlen( $zp_request_queue[$zp_item[0]]["items"] ) != 0 ) |
| 146 |
$temp_item_key = ",".$temp_item_key; |
| 147 |
|
| 148 |
$zp_request_queue[$zp_item[0]]["items"] .= $temp_item_key; |
| 149 |
} |
| 150 |
} |
| 151 |
} |
| 152 |
|
| 153 |
|
| 154 |
|
| 155 |
// +--------------------+ |
| 156 |
// | Build request URLs | |
| 157 |
// +--------------------+ |
| 158 |
|
| 159 |
if ( $zp_request_queue !== [] ) |
| 160 |
{ |
| 161 |
// REVIEW: Does setting $zp_request_queue here overwrite it for each account? |
| 162 |
foreach ( $zp_request_queue as $api_user_id => $zp_request_data ) |
| 163 |
$zp_request_queue = Zotpress_prep_request_URL( $wpdb, $zpr, $zp_request_queue, $api_user_id, $zp_request_data ); |
| 164 |
} |
| 165 |
else |
| 166 |
{ |
| 167 |
$zp_request_queue = Zotpress_prep_request_URL( $wpdb, $zpr, $zp_request_queue ); |
| 168 |
} |
| 169 |
|
| 170 |
|
| 171 |
|
| 172 |
|
| 173 |
// +---------+ |
| 174 |
// | TESTING | |
| 175 |
// +---------+ |
| 176 |
|
| 177 |
// var_dump($zp_request_queue);exit; |
| 178 |
|
| 179 |
// if ( $zpr["request_start"] == 50 ) { |
| 180 |
// var_dump("shortcode.request.php TESTING: "); |
| 181 |
// print_r($_GET); var_dump("<br /><br />url: ".$zp_import_url); |
| 182 |
// var_dump(" AFTER \n\n"); |
| 183 |
// } |
| 184 |
|
| 185 |
|
| 186 |
|
| 187 |
|
| 188 |
|
| 189 |
|
| 190 |
// +------------------+ |
| 191 |
// | Request the data | |
| 192 |
// +------------------+ |
| 193 |
|
| 194 |
$zp_request = array(); |
| 195 |
$zp_error = false; |
| 196 |
$zp_usecache = false; |
| 197 |
$zp_updateneeded = false; |
| 198 |
|
| 199 |
// Account for missing/unsynced accounts or no requests |
| 200 |
if ( $zp_request_queue === false ) |
| 201 |
$zp_error = "Zotpress account not found."; |
| 202 |
|
| 203 |
// New in 12.3.13: Check for missing data |
| 204 |
// if ( $zp_import_contents->request_error ) |
| 205 |
|
| 206 |
|
| 207 |
if ( ! $zp_error ) |
| 208 |
{ |
| 209 |
foreach ( $zp_request_queue as $zp_request_account ) |
| 210 |
{ |
| 211 |
// Multiple/more than one request |
| 212 |
if ( count($zp_request_account["requests"]) > 1 ) |
| 213 |
{ |
| 214 |
foreach ( $zp_request_account["requests"] as $zp_request_url ) |
| 215 |
{ |
| 216 |
// Check the cache with PHP |
| 217 |
if ( $checkcache && ! $zpr["request_update"] ) |
| 218 |
{ |
| 219 |
$zp_checkcache = $zp_import_contents->get_request_cache( $zp_request_url, $zpr["update"] ); |
| 220 |
$zp_checkcache_json = json_decode( $zp_checkcache['json'] ); |
| 221 |
|
| 222 |
if ( gettype($zp_checkcache_json) != 'array' |
| 223 |
&& property_exists($zp_checkcache_json, 'status') |
| 224 |
&& $zp_checkcache_json->status == 'No Cache' ) |
| 225 |
{ |
| 226 |
// $zp_usecache = false; |
| 227 |
} |
| 228 |
else // Continue as normal with cache |
| 229 |
{ |
| 230 |
$zp_imported = $zp_checkcache; |
| 231 |
$zp_usecache = true; |
| 232 |
} |
| 233 |
} |
| 234 |
else // Otherwise, assume JS Ajax |
| 235 |
{ |
| 236 |
$zp_imported = $zp_import_contents->get_request_contents( $zp_request_url, $zpr["update"] ); |
| 237 |
|
| 238 |
if ( $zp_imported["updateneeded"] ) |
| 239 |
$zp_updateneeded = true; |
| 240 |
} |
| 241 |
|
| 242 |
// Stop and let JS Ajax take over |
| 243 |
if ( $checkcache && ! $zp_usecache ) |
| 244 |
continue; |
| 245 |
|
| 246 |
// Deal with possible errors |
| 247 |
if ( gettype($zp_imported) == "string" |
| 248 |
&& substr($zp_imported, 0, 5) == "Error" ) |
| 249 |
{ |
| 250 |
$zp_error = substr($zp_imported, 7, -1); |
| 251 |
continue; |
| 252 |
} |
| 253 |
|
| 254 |
// Create all-requests json if doesn't exists |
| 255 |
if ( empty($zp_request) ) |
| 256 |
$zp_request = $zp_imported; |
| 257 |
|
| 258 |
// Add to existing all-requests json |
| 259 |
$zp_request["json"] = rtrim($zp_request["json"], "]") . "," . $zp_imported["json"] . "]"; |
| 260 |
} |
| 261 |
} |
| 262 |
|
| 263 |
// Just one request |
| 264 |
else |
| 265 |
{ |
| 266 |
// First, check the cache with PHP |
| 267 |
if ( $checkcache |
| 268 |
&& ! $zpr["request_update"] ) |
| 269 |
{ |
| 270 |
$zp_checkcache = $zp_import_contents->get_request_cache( $zp_request_account["requests"][0], $zpr["update"] ); |
| 271 |
$zp_checkcache_json = json_decode( $zp_checkcache['json'], false ); |
| 272 |
|
| 273 |
if ( gettype($zp_checkcache_json) != 'array' |
| 274 |
&& property_exists($zp_checkcache_json, 'status') |
| 275 |
&& $zp_checkcache_json->status == 'No Cache' ) |
| 276 |
{ |
| 277 |
// $zp_usecache = false; |
| 278 |
} |
| 279 |
else // Continue as normal with cache |
| 280 |
{ |
| 281 |
$zp_imported = $zp_checkcache; |
| 282 |
$zp_usecache = true; |
| 283 |
} |
| 284 |
|
| 285 |
// if ( $zp_checkcache["updateneeded"] ) |
| 286 |
// $zp_updateneeded = true; |
| 287 |
|
| 288 |
} |
| 289 |
else if ( $zpr["request_update"] ) |
| 290 |
{ |
| 291 |
$zp_imported = $zp_import_contents->get_request_update( $zp_request_account["requests"][0], $zpr["update"] ); |
| 292 |
} |
| 293 |
else // Otherwise, assume JS AJAX |
| 294 |
{ |
| 295 |
$zp_imported = $zp_import_contents->get_request_contents( $zp_request_account["requests"][0], $zpr["update"] ); |
| 296 |
|
| 297 |
if ( isset($zp_imported["updateneeded"]) ) |
| 298 |
$zp_updateneeded = true; |
| 299 |
} |
| 300 |
|
| 301 |
// Stop and let JS Ajax take over |
| 302 |
if ( ( $checkcache |
| 303 |
&& ! $zp_usecache ) ) |
| 304 |
continue; |
| 305 |
|
| 306 |
// Deal with possible error |
| 307 |
if ( gettype($zp_imported) == "string" |
| 308 |
&& substr($zp_imported, 0, 5) == "Error" ) |
| 309 |
{ |
| 310 |
$zp_error = substr($zp_imported, 7, -1); |
| 311 |
} |
| 312 |
|
| 313 |
// Create all-requests json if doesn't exists |
| 314 |
else |
| 315 |
{ |
| 316 |
if ( empty($zp_request) ) |
| 317 |
{ |
| 318 |
$zp_request = $zp_imported; |
| 319 |
} |
| 320 |
|
| 321 |
else // Add to existing all-requests json |
| 322 |
{ |
| 323 |
$zp_request["json"] = rtrim($zp_request["json"], "]") . "," . ltrim($zp_imported["json"], "[") . "]"; |
| 324 |
} |
| 325 |
} |
| 326 |
|
| 327 |
// 7.4 Update: Might not exist? |
| 328 |
if ( ! isset($zp_request["json"]) ) |
| 329 |
$zp_error = "JSON not found"; |
| 330 |
elseif ( isset($zp_request["json"]) && $zp_request["json"] == "Not found" ) |
| 331 |
$zp_error = $zp_request["json"]; |
| 332 |
|
| 333 |
// } elseif ( empty($zp_request) ) { |
| 334 |
// $zp_request = $zp_imported; |
| 335 |
// } else // Add to existing all-requests json |
| 336 |
// { |
| 337 |
// $zp_request["json"] = rtrim($zp_request["json"], "]") . "," . ltrim($zp_imported["json"], "[") . "]"; |
| 338 |
// } |
| 339 |
} // Just one request |
| 340 |
} // Request the data (foreach) |
| 341 |
} // If no error |
| 342 |
|
| 343 |
// Fix formatting quirk |
| 344 |
if ( ( ! $checkcache && ! $zp_error ) |
| 345 |
|| ( $checkcache && $zp_usecache && ! $zp_error ) ) |
| 346 |
$zp_request["json"] = str_replace("}}]]", "}}]", $zp_request["json"]); |
| 347 |
|
| 348 |
if ( ( ! $checkcache && ( ! $zp_error && $zp_request["json"] != "0" ) ) |
| 349 |
|| ( $checkcache && $zp_usecache && ( ! $zp_error && $zp_request["json"] != "0" ) ) ) |
| 350 |
{ |
| 351 |
// Decode the JSONs |
| 352 |
// Thanks to Adnreea Onica @ StackOverflow |
| 353 |
$temp_headers = json_decode( $zp_request["headers"] ); |
| 354 |
// $temp_headers = json_encode( (array)$zp_request["headers"] ); |
| 355 |
// $temp_headers = json_decode( str_replace('\u0000*\u0000','', $temp_headers) ); |
| 356 |
|
| 357 |
// $temp_data = json_encode( (array)$zp_request["json"] ); |
| 358 |
// $temp_data = json_decode( str_replace('\u0000*\u0000','', $temp_data) ); |
| 359 |
$temp_data = json_decode( $zp_request["json"] ); |
| 360 |
|
| 361 |
// Figure out if there's multiple requests and how many |
| 362 |
// if ( $zpr["request_start"] == 0 |
| 363 |
// && ( property_exists($temp_headers, 'link') |
| 364 |
// && $temp_headers->link !== null ) |
| 365 |
// && strpos( $temp_headers->link, 'rel="last"' ) !== false ) |
| 366 |
|
| 367 |
if ( $zpr["request_start"] == 0 |
| 368 |
&& isset( $temp_headers->link ) |
| 369 |
&& strpos( $temp_headers->link, 'rel="last"' ) !== false ) |
| 370 |
{ |
| 371 |
$temp_link = explode( ";", $temp_headers->link ); |
| 372 |
$temp_link = explode( "start=", $temp_link[1] ); |
| 373 |
$temp_link = explode( "&", $temp_link[1] ); |
| 374 |
|
| 375 |
// // FIX: Accounted for limit ...? |
| 376 |
// if ( $zpr["limit"] ) { |
| 377 |
// $zp_request_meta["request_last"] = (int) $zpr["limit"]; |
| 378 |
// } |
| 379 |
// else { |
| 380 |
$zp_request_meta["request_last"] = (int) $temp_link[0]; |
| 381 |
// } |
| 382 |
} |
| 383 |
|
| 384 |
// Figure out the next starting position for the next request, if any |
| 385 |
// 7.3.3: Changed from >= to > |
| 386 |
if ( $zp_request_meta["request_last"] >= ($zpr["request_start"] + $zpr["limit"]) ) { |
| 387 |
|
| 388 |
// 7.3.9: Only if next is greater than limit |
| 389 |
$zp_request_meta["request_next"] = $zpr["request_start"] + $zpr["limit"]; |
| 390 |
} |
| 391 |
|
| 392 |
// Overwrite request if limit |
| 393 |
// 7.3.3: Fix for collections? |
| 394 |
if ( ( $zpr["item_type"] == "items" || $zpr["item_type"] == "collections" ) |
| 395 |
&& $zpr["overwrite_request"] === true ) |
| 396 |
{ |
| 397 |
$zp_request_meta["request_next"] = 0; |
| 398 |
$zp_request_meta["request_last"] = 0; |
| 399 |
} |
| 400 |
|
| 401 |
// Overwrite last_request |
| 402 |
if ( $zpr["overwrite_last_request"] ) |
| 403 |
{ |
| 404 |
// Make sure it's less than the total available items |
| 405 |
if ( isset( $temp_headers->{"total-results"} ) |
| 406 |
&& $temp_headers->{"total-results"} < $zpr["overwrite_last_request"] ) |
| 407 |
$zpr["overwrite_last_request"] = (int) (ceil( (int) $temp_headers->{"total-results"} / $zpr["limit"] ) - 1) * $zpr["limit"]; |
| 408 |
else |
| 409 |
$zpr["overwrite_last_request"] = (int) ceil( $zpr["overwrite_last_request"] / $zpr["limit"] ) * $zpr["limit"]; |
| 410 |
|
| 411 |
$zp_request_meta["request_last"] = $zpr["overwrite_last_request"]; |
| 412 |
} |
| 413 |
|
| 414 |
|
| 415 |
// +-----------------+ |
| 416 |
// | Format the data | |
| 417 |
// +-----------------+ |
| 418 |
|
| 419 |
if ( count($temp_data) > 0 ) |
| 420 |
{ |
| 421 |
// If single, place the object into an array |
| 422 |
if ( gettype($temp_data) == "object" ) |
| 423 |
{ |
| 424 |
$temp = $temp_data; |
| 425 |
$temp_data = array(); |
| 426 |
$temp_data[0] = $temp; |
| 427 |
} |
| 428 |
|
| 429 |
// Set up conditional vars |
| 430 |
if ( $zpr["shownotes"] ) $zp_notes_num = 1; |
| 431 |
if ( $zpr["showimage"] ) $zp_showimage_keys = ""; |
| 432 |
|
| 433 |
// Get individual items |
| 434 |
foreach ( $temp_data as $item ) |
| 435 |
{ |
| 436 |
// Set target for links |
| 437 |
$zp_target_output = ""; |
| 438 |
if ( $zpr["target"] ) |
| 439 |
$zp_target_output = "target='_blank' "; |
| 440 |
|
| 441 |
// Author filtering: skip non-matching authors |
| 442 |
// TODO: Breaking with multi name |
| 443 |
// EVENTUAL TODO: Zotero API 3 searches title and author, so wrong authors can appear |
| 444 |
if ( $zpr["author"] |
| 445 |
&& count($item->data->creators) > 0 ) |
| 446 |
{ |
| 447 |
$zp_authors_check = false; |
| 448 |
|
| 449 |
// 7.3.10: CHECK: Have to replace the apostrophe entity ... |
| 450 |
$zpr["author"] = str_replace('#039;', "'", $zpr["author"]); |
| 451 |
|
| 452 |
// Deal with multiple authors |
| 453 |
if ( gettype($zpr["author"]) != "array" |
| 454 |
&& strpos($zpr["author"], ",") !== false ) |
| 455 |
{ |
| 456 |
$zp_authors = explode( ",", $zpr["author"] ); |
| 457 |
|
| 458 |
foreach ( $zp_authors as $author ) |
| 459 |
if ( zotpress_check_author_continue( $item, $author ) === true ) |
| 460 |
$zp_authors_check = true; |
| 461 |
} |
| 462 |
|
| 463 |
// Single author or inclusive |
| 464 |
else |
| 465 |
{ |
| 466 |
if ( $zpr["inclusive"] === false ) |
| 467 |
{ |
| 468 |
// 7.3.10: CHECK: Why is this assuming 1? Setting to 0: |
| 469 |
$author_exists_count = 0; |
| 470 |
|
| 471 |
// 7.3.10: CHECK: Not always an array ... |
| 472 |
if ( is_array($zpr["author"]) ) { |
| 473 |
|
| 474 |
foreach ( $zpr["author"] as $author ) |
| 475 |
if ( zotpress_check_author_continue( $item, $author ) === true ) |
| 476 |
$author_exists_count++; |
| 477 |
|
| 478 |
// if ( $author_exists_count == count($zpr["author"]) +1 ) |
| 479 |
if ( $author_exists_count == count($zpr["author"]) ) |
| 480 |
$zp_authors_check = true; |
| 481 |
} |
| 482 |
else { // Just a string/single author |
| 483 |
|
| 484 |
if ( zotpress_check_author_continue( $item, $zpr["author"] ) === true ) |
| 485 |
$zp_authors_check = true; |
| 486 |
} |
| 487 |
|
| 488 |
} |
| 489 |
else // inclusive and single |
| 490 |
{ |
| 491 |
if ( zotpress_check_author_continue( $item, $zpr["author"] ) === true ) |
| 492 |
$zp_authors_check = true; |
| 493 |
} |
| 494 |
|
| 495 |
// } elseif (zotpress_check_author_continue( $item, $zpr["author"] ) === true) { |
| 496 |
// $zp_authors_check = true; |
| 497 |
// } |
| 498 |
} |
| 499 |
|
| 500 |
if ( $zp_authors_check === false ) |
| 501 |
continue; |
| 502 |
} // author |
| 503 |
|
| 504 |
// Year filtering: skip non-matching years |
| 505 |
if ( $zpr["year"] |
| 506 |
&& property_exists($item->meta, "parsedDate") ) |
| 507 |
{ |
| 508 |
// multiple |
| 509 |
if ( strpos($zpr["year"], ",") !== false ) |
| 510 |
{ |
| 511 |
$zp_years_check = false; |
| 512 |
$zp_years = explode( ",", $zpr["year"] ); |
| 513 |
|
| 514 |
foreach ( $zp_years as $year ) |
| 515 |
if ( zotpress_get_year( $item->meta->parsedDate ) == $year ) |
| 516 |
$zp_years_check = true; |
| 517 |
|
| 518 |
if ( ! $zp_years_check ) |
| 519 |
continue; |
| 520 |
} |
| 521 |
else // single |
| 522 |
{ |
| 523 |
if ( zotpress_get_year( $item->meta->parsedDate ) != $zpr["year"] ) |
| 524 |
continue; |
| 525 |
} |
| 526 |
// } elseif (zotpress_get_year( $item->meta->parsedDate ) != $zpr["year"]) { |
| 527 |
// continue; |
| 528 |
// } |
| 529 |
} |
| 530 |
|
| 531 |
// Skip non-matching years for author-year pairs |
| 532 |
// if ( $zpr["year"] && $zpr["author"] && (property_exists($item->meta, 'parsedDate') && $item->meta->parsedDate !== null) && zotpress_get_year( $item->meta->parsedDate ) != $zpr["year"] ) |
| 533 |
if ( $zpr["year"] |
| 534 |
&& $zpr["author"] |
| 535 |
&& isset($item->meta->parsedDate) ) |
| 536 |
continue; |
| 537 |
|
| 538 |
// Add item key for show image |
| 539 |
if ( $zpr["showimage"] ) $zp_showimage_keys .= " ".$item->key; |
| 540 |
|
| 541 |
// Modify style based on language |
| 542 |
// Languages: jp |
| 543 |
if ( isset($item->data->language) |
| 544 |
// && $item->data->language !== null |
| 545 |
// && $item->data->language != "" |
| 546 |
&& $item->data->language == "ja" ) |
| 547 |
{ |
| 548 |
// Change ", and " to comma |
| 549 |
$item->bib = str_ireplace(", and ", ", ", $item->bib); |
| 550 |
|
| 551 |
// Remove "In " |
| 552 |
$item->bib = str_ireplace("In ", "", $item->bib); |
| 553 |
} |
| 554 |
|
| 555 |
// Hyperlink or URL Wrap |
| 556 |
if ( isset($item->data->url) |
| 557 |
// && $item->data->url !== null |
| 558 |
&& strlen($item->data->url) > 0 ) |
| 559 |
{ |
| 560 |
if ( $zpr["urlwrap"] |
| 561 |
&& $zpr["urlwrap"] == "title" |
| 562 |
&& $item->data->title ) |
| 563 |
{ |
| 564 |
// First: Get rid of text URL if it appears as text in the citation: |
| 565 |
// REVIEW: Does this account for all citation styles? |
| 566 |
/* chicago-author-date */ $item->bib = str_ireplace( htmlentities($item->data->url."."), "", $item->bib ); // Note the period |
| 567 |
/* APA */ $item->bib = str_ireplace( htmlentities($item->data->url), "", $item->bib ); |
| 568 |
|
| 569 |
// 7.3.14 (@timtom): Fix APA citation by removing the last part of the "Retrieved from" text |
| 570 |
$item->bib = preg_replace('/(Retrieved \w+ \d+, \d+)(, from)/','${1}.',$item->bib); |
| 571 |
|
| 572 |
$item->bib = str_ireplace( " Retrieved from ", "", $item->bib ); |
| 573 |
$item->bib = str_ireplace( " Available from: ", "", $item->bib ); |
| 574 |
|
| 575 |
|
| 576 |
// Next, get rid of double space characters (two space characters next to each other): |
| 577 |
$item->bib = preg_replace( '/ /', ' ', preg_replace( '/[[:blank:]]+/', ' ', $item->bib ) ); |
| 578 |
$item->data->title = preg_replace( '/ /', ' ', preg_replace( '/[[:blank:]]+/', ' ', $item->data->title ) ); |
| 579 |
|
| 580 |
|
| 581 |
// Next, replace space entities with real spaces: |
| 582 |
$item->bib = str_ireplace(" ", " ", $item->bib ); |
| 583 |
$item->data->title = str_ireplace(" ", " ", $item->data->title ); |
| 584 |
|
| 585 |
|
| 586 |
// Next, replace entity quotes: |
| 587 |
$item->bib = str_ireplace( "“", """, |
| 588 |
str_ireplace( "”", """, |
| 589 |
htmlentities( |
| 590 |
html_entity_decode( $item->bib, ENT_QUOTES, "UTF-8" ), |
| 591 |
ENT_QUOTES, |
| 592 |
"UTF-8" |
| 593 |
) |
| 594 |
) |
| 595 |
); |
| 596 |
$item->data->title = str_ireplace( "“", """, |
| 597 |
str_ireplace( "”", """, |
| 598 |
htmlentities( |
| 599 |
html_entity_decode( $item->data->title, ENT_QUOTES, "UTF-8" ), |
| 600 |
ENT_QUOTES, |
| 601 |
"UTF-8" |
| 602 |
) |
| 603 |
) |
| 604 |
); |
| 605 |
|
| 606 |
|
| 607 |
// Next, replace special Word characters: |
| 608 |
// Thanks to Walter Tross @ Stack Overflow; CC BY-SA 3.0: https://creativecommons.org/licenses/by-sa/3.0/ |
| 609 |
$chr_map = array( |
| 610 |
"\xC2\x82" => "'", // U+0082U+201A single low-9 quotation mark |
| 611 |
"\xC2\x84" => '"', // U+0084U+201E double low-9 quotation mark |
| 612 |
"\xC2\x8B" => "'", // U+008BU+2039 single left-pointing angle quotation mark |
| 613 |
"\xC2\x91" => "'", // U+0091U+2018 left single quotation mark |
| 614 |
"\xC2\x92" => "'", // U+0092U+2019 right single quotation mark |
| 615 |
"\xC2\x93" => '"', // U+0093U+201C left double quotation mark |
| 616 |
"\xC2\x94" => '"', // U+0094U+201D right double quotation mark |
| 617 |
"\xC2\x9B" => "'", // U+009BU+203A single right-pointing angle quotation mark |
| 618 |
"\xC2\xAB" => '"', // U+00AB left-pointing double angle quotation mark |
| 619 |
"\xC2\xBB" => '"', // U+00BB right-pointing double angle quotation mark |
| 620 |
"\xE2\x80\x98" => "'", // U+2018 left single quotation mark |
| 621 |
"\xE2\x80\x99" => "'", // U+2019 right single quotation mark |
| 622 |
"\xE2\x80\x9A" => "'", // U+201A single low-9 quotation mark |
| 623 |
"\xE2\x80\x9B" => "'", // U+201B single high-reversed-9 quotation mark |
| 624 |
"\xE2\x80\x9C" => '"', // U+201C left double quotation mark |
| 625 |
"\xE2\x80\x9D" => '"', // U+201D right double quotation mark |
| 626 |
"\xE2\x80\x9E" => '"', // U+201E double low-9 quotation mark |
| 627 |
"\xE2\x80\x9F" => '"', // U+201F double high-reversed-9 quotation mark |
| 628 |
"\xE2\x80\xB9" => "'", // U+2039 single left-pointing angle quotation mark |
| 629 |
"\xE2\x80\xBA" => "'", // U+203A single right-pointing angle quotation mark |
| 630 |
"\xE2\x80\xAF" => " " // 7.3.14 (@timtom): U+206F nominal digit shapes |
| 631 |
); |
| 632 |
$chr = array_keys( $chr_map ); |
| 633 |
$rpl = array_values( $chr_map ); |
| 634 |
$item->bib = str_ireplace( $chr, $rpl, html_entity_decode( $item->bib, ENT_QUOTES, "UTF-8" ) ); |
| 635 |
$item->data->title = str_ireplace( $chr, $rpl, html_entity_decode( $item->data->title, ENT_QUOTES, "UTF-8" ) ); |
| 636 |
|
| 637 |
// Re-encode for foreign characters, but don't encode quotes: |
| 638 |
$item->bib = htmlentities( $item->bib, ENT_NOQUOTES, "UTF-8" ); |
| 639 |
$item->data->title = htmlentities( $item->data->title, ENT_NOQUOTES, "UTF-8" ); |
| 640 |
|
| 641 |
|
| 642 |
// Next, prep title: |
| 643 |
// $item->data->title = htmlentities( $item->data->title, ENT_COMPAT, "UTF-8" ); |
| 644 |
|
| 645 |
|
| 646 |
// If wrapping title, wrap it: |
| 647 |
$item->bib = str_ireplace( |
| 648 |
$item->data->title, |
| 649 |
"<a class='zp-ItemURL' ".$zp_target_output."href='".$item->data->url."'>".$item->data->title."</a>", |
| 650 |
$item->bib |
| 651 |
); |
| 652 |
|
| 653 |
// Finally, revert bib entities: |
| 654 |
$item->bib = html_entity_decode( $item->bib, ENT_QUOTES, "UTF-8" ); |
| 655 |
$item->data->title = html_entity_decode( $item->data->title, ENT_QUOTES, "UTF-8" ); |
| 656 |
|
| 657 |
} |
| 658 |
else // Just hyperlink the URL text |
| 659 |
{ |
| 660 |
$item->bib = str_ireplace( |
| 661 |
htmlentities($item->data->url), |
| 662 |
"<a class='zp-ItemURL' ".$zp_target_output."href='".$item->data->url."'>".$item->data->url."</a>", |
| 663 |
$item->bib |
| 664 |
); |
| 665 |
} |
| 666 |
} // Hyperlink or URL wrap |
| 667 |
|
| 668 |
// Hyperlink DOIs |
| 669 |
if ( isset($item->data->DOI) |
| 670 |
// && $item->data->DOI !== null |
| 671 |
&& strlen($item->data->DOI) > 0 ) |
| 672 |
{ |
| 673 |
// Styles without http |
| 674 |
if ( strpos( $item->bib, "doi:" ) !== false |
| 675 |
&& strpos( $item->bib, "doi.org" ) == false ) |
| 676 |
{ |
| 677 |
$item->bib = str_ireplace( |
| 678 |
"doi:" . $item->data->DOI, |
| 679 |
"<a class='zp-DOIURL' ".$zp_target_output."href='http://doi.org/".$item->data->DOI."'>http://doi.org/".$item->data->DOI."</a>", |
| 680 |
$item->bib |
| 681 |
); |
| 682 |
} |
| 683 |
// Styles with http |
| 684 |
elseif ( strpos( $item->bib, "http://doi.org/" ) !== false |
| 685 |
&& strpos( $item->bib, "</a>" ) == false ) |
| 686 |
{ |
| 687 |
$item->bib = str_ireplace( |
| 688 |
"http://doi.org/" . $item->data->DOI, |
| 689 |
"<a class='zp-DOIURL' ".$zp_target_output."href='http://doi.org/".$item->data->DOI."'>http://doi.org/".$item->data->DOI."</a>", |
| 690 |
$item->bib |
| 691 |
); |
| 692 |
} |
| 693 |
// HTTPS format |
| 694 |
elseif ( strpos( $item->bib, "https://doi.org/" ) !== false |
| 695 |
&& strpos( $item->bib, "</a>" ) == false ) |
| 696 |
{ |
| 697 |
$item->bib = str_ireplace( |
| 698 |
"https://doi.org/" . $item->data->DOI, |
| 699 |
"<a class='zp-DOIURL' ".$zp_target_output."href='https://doi.org/".$item->data->DOI."'>https://doi.org/".$item->data->DOI."</a>", |
| 700 |
$item->bib |
| 701 |
); |
| 702 |
} |
| 703 |
} |
| 704 |
|
| 705 |
// Cite link (RIS) |
| 706 |
if ( $zpr["citeable"] ) { |
| 707 |
|
| 708 |
// REVIEW: Why is this needed? Why is api_user_id empty sometimes? |
| 709 |
$tempUserId = ''; |
| 710 |
if ( isset($api_user_id) ) |
| 711 |
$tempUserId = $api_user_id; |
| 712 |
else |
| 713 |
$tempUserId = $zpr["api_user_id"]; |
| 714 |
|
| 715 |
$item->bib = preg_replace( '~(.*)' . preg_quote('</div>', '~') . '(.*?)~', '$1' . " <a title='Cite in RIS Format' class='zp-CiteRIS' data-zp-cite='api_user_id=".$tempUserId."&item_key=".$item->key."' href='javascript:void(0);'>Cite</a> </div>" . '$2', $item->bib, 1 ); |
| 716 |
// $item->bib = preg_replace( '~(.*)' . preg_quote('</div>', '~') . '(.*?)~', '$1' . " <a title='Cite in RIS Format' class='zp-CiteRIS' href='".ZOTPRESS_PLUGIN_URL."lib/request/request.cite.php?api_user_id=".$tempUserId."&item_key=".$item->key."'>Cite</a> </div>" . '$2', $item->bib, 1 ); |
| 717 |
// $item->bib = preg_replace( '~(.*)' . preg_quote('</div>', '~') . '(.*?)~', '$1' . " <a title='Cite in RIS Format' class='zp-CiteRIS' href='".ZOTPRESS_PLUGIN_URL."lib/request/request.cite.php?api_user_id=".$zpr["api_user_id"]."&item_key=".$item->key."'>Cite</a> </div>" . '$2', $item->bib, 1 ); |
| 718 |
} |
| 719 |
|
| 720 |
// Highlight text |
| 721 |
if ( $zpr["highlight"] ) |
| 722 |
$item->bib = str_ireplace( $zpr["highlight"], "<strong>".$zpr["highlight"]."</strong>", $item->bib ); |
| 723 |
|
| 724 |
// Downloads, notes |
| 725 |
if ( $zpr["downloadable"] |
| 726 |
|| $zpr["shownotes"] ) |
| 727 |
{ |
| 728 |
// Check if item has children that could be downloads |
| 729 |
if ( $item->meta->numChildren > 0 ) |
| 730 |
{ |
| 731 |
// REVIEW: Why is this needed? Why is api_user_id empty sometimes? |
| 732 |
$tempUserId = ''; |
| 733 |
if ( isset($api_user_id) ) |
| 734 |
$tempUserId = $api_user_id; |
| 735 |
else |
| 736 |
$tempUserId = $zpr["api_user_id"]; |
| 737 |
|
| 738 |
// Get the user's account |
| 739 |
$zp_account = zotpress_get_account ($wpdb, $tempUserId); |
| 740 |
|
| 741 |
$zp_child_url = "https://api.zotero.org/".$zp_account[0]->account_type."/".$tempUserId."/items"; |
| 742 |
$zp_child_url .= "/".$item->key."/children?"; |
| 743 |
if (!is_null($zp_account[0]->public_key) && trim($zp_account[0]->public_key) != "") |
| 744 |
$zp_child_url .= "key=".$zp_account[0]->public_key."&"; |
| 745 |
$zp_child_url .= "&format=json&include=data"; |
| 746 |
|
| 747 |
// Get data |
| 748 |
$zp_import_child = new ZotpressRequest(); |
| 749 |
$zp_child_request = $zp_import_child->get_request_contents( $zp_child_url, $zpr["update"] ); |
| 750 |
$zp_children = json_decode( $zp_child_request["json"] ); |
| 751 |
|
| 752 |
// If the item changes and no longer exists on |
| 753 |
// the Zotero side, it will return an error message |
| 754 |
if ( ! is_null($zp_children) |
| 755 |
&& $zp_children != "Item not found" ) |
| 756 |
{ |
| 757 |
$zp_download_meta = false; |
| 758 |
$zp_notes_meta = array(); |
| 759 |
|
| 760 |
foreach ( $zp_children as $zp_child ) |
| 761 |
{ |
| 762 |
// Check for downloads |
| 763 |
if ( $zpr["downloadable"] ) |
| 764 |
{ |
| 765 |
// Check for downloadable file (attached) |
| 766 |
if ( isset($zp_child->data->linkMode) |
| 767 |
&& ( ( $zp_child->data->linkMode == "imported_file" |
| 768 |
|| $zp_child->data->linkMode == "imported_url" ) |
| 769 |
&& preg_match('(pdf|doc|docx|ppt|pptx|latex|rtf|odt|odp)', $zp_child->data->filename) === 1 ) ) |
| 770 |
{ |
| 771 |
$zp_download_meta = array ( |
| 772 |
"dlkey" => $zp_child->key, |
| 773 |
"contentType" => $zp_child->data->contentType |
| 774 |
); |
| 775 |
|
| 776 |
// Display download link if file exists |
| 777 |
if ( $zp_download_meta !== [] ) { |
| 778 |
$item->bib = preg_replace('~(.*)' . preg_quote( '</div>', '~') . '(.*?)~', '$1' . " <a title='Download' class='zp-DownloadURL zp-getDownloadURL' data-zp-dl='api_user_id=".$tempUserId."&dlkey=".$zp_download_meta["dlkey"]."&content_type=".$zp_download_meta["contentType"]."' href='javascript:void(0);'>Download</a></div>" . '$2', $item->bib, 1 ); |
| 779 |
// $item->bib = preg_replace('~(.*)' . preg_quote( '</div>', '~') . '(.*?)~', '$1' . " <a title='Download' class='zp-DownloadURL zp-getDownloadURL' href='".ZOTPRESS_PLUGIN_URL."lib/request/request.dl.php?api_user_id=".$tempUserId."&dlkey=".$zp_download_meta["dlkey"]."&content_type=".$zp_download_meta["contentType"]."'>Download</a></div>" . '$2', $item->bib, 1 ); |
| 780 |
} |
| 781 |
} |
| 782 |
|
| 783 |
// Check for link to downloadable file (third-party) |
| 784 |
else if ( isset($zp_child->data->linkMode) |
| 785 |
&& ( $zp_child->data->linkMode == "linked_url" |
| 786 |
&& preg_match('(pdf|doc|docx|ppt|pptx|latex|rtf|odt|odp)', $zp_child->data->url) === 1 ) ) |
| 787 |
{ |
| 788 |
$item->bib = preg_replace('~(.*)' . preg_quote( '</div>', '~') . '(.*?)~', '$1' . " <a title='Download' class='zp-DownloadURL' href='".$zp_child->data->url."'>Download</a></div>" . '$2', $item->bib, 1 ); |
| 789 |
} |
| 790 |
} |
| 791 |
|
| 792 |
// Check for notes |
| 793 |
if ( $zpr["shownotes"] |
| 794 |
&& ( isset($zp_child->data->itemType) |
| 795 |
&& $zp_child->data->itemType == "note" ) ) |
| 796 |
{ |
| 797 |
$zp_notes_meta[count($zp_notes_meta)] = $zp_child->data->note; |
| 798 |
} |
| 799 |
} |
| 800 |
|
| 801 |
// // Display download link if file exists |
| 802 |
// if ( $zp_download_meta ) |
| 803 |
// $item->bib = preg_replace('~(.*)' . preg_quote( '</div>', '~') . '(.*?)~', '$1' . " <a title='Download' class='zp-DownloadURL' href='".ZOTPRESS_PLUGIN_URL."lib/request/request.dl.php?api_user_id=".$zpr["api_user_id"]."&dlkey=".$zp_download_meta["dlkey"]."&content_type=".$zp_download_meta["contentType"]."'>Download</a></div>" . '$2', $item->bib, 1 ); |
| 804 |
|
| 805 |
// Display notes, if any |
| 806 |
if ( $zp_notes_meta !== [] ) |
| 807 |
{ |
| 808 |
$temp_notes = "<li id=\"zp-Note-".$item->key."\">\n"; |
| 809 |
|
| 810 |
if ( count($zp_notes_meta) == 1 ) |
| 811 |
{ |
| 812 |
$temp_notes .= $zp_notes_meta[0]."\n"; |
| 813 |
} |
| 814 |
else // multiple |
| 815 |
{ |
| 816 |
$temp_notes .= "<ul class='zp-Citation-Item-Notes'>\n"; |
| 817 |
|
| 818 |
foreach ($zp_notes_meta as $zp_note_meta) |
| 819 |
$temp_notes .= "<li class='zp-Citation-note'>" . $zp_note_meta . "\n</li>\n"; |
| 820 |
|
| 821 |
$temp_notes .= "\n</ul><!-- .zp-Citation-Item-Notes -->\n\n"; |
| 822 |
} |
| 823 |
|
| 824 |
// Add to item |
| 825 |
$item->notes = $temp_notes . "</li>\n"; |
| 826 |
|
| 827 |
// Add note reference to citation |
| 828 |
$note_class = "zp-Notes-Reference"; if ( is_admin_bar_showing() ) $note_class .= " zp-Admin-Bar-Showing"; |
| 829 |
$item->bib = preg_replace('~(.*)' . preg_quote('</div>', '~') . '(.*?)~', '$1' . " <sup class=\"".$note_class."\"><a href=\"#zp-Note-".$item->key."\">".$zp_notes_num."</a></sup> </div>" . '$2', $item->bib, 1); |
| 830 |
$zp_notes_num++; |
| 831 |
} |
| 832 |
} // Children exist; not "Item not found" |
| 833 |
} // Check if item has children |
| 834 |
} // $zpr["downloadable"] |
| 835 |
|
| 836 |
$zp_all_the_data[] = $item; |
| 837 |
|
| 838 |
} // foreach item |
| 839 |
|
| 840 |
// Show tags |
| 841 |
if ( $zpr["showtags"] ) |
| 842 |
{ |
| 843 |
// Decode JSON format |
| 844 |
$zp_tags = json_decode( $zp_request["tags"] ); |
| 845 |
|
| 846 |
// Just add to the data; let the front-end handle the display |
| 847 |
// i.e., add to item.data.tags |
| 848 |
foreach ( $zp_all_the_data as $id => $data ) |
| 849 |
{ |
| 850 |
// Tags are connected to item key |
| 851 |
if ( property_exists( $zp_tags, $data->key ) ) |
| 852 |
$zp_all_the_data[$id]->data->tags = $zp_tags->{$data->key}; |
| 853 |
} |
| 854 |
} |
| 855 |
|
| 856 |
|
| 857 |
// Show images |
| 858 |
if ( $zpr["showimage"] ) |
| 859 |
{ |
| 860 |
// Get images for all item keys from zpdb, if they exist |
| 861 |
$zp_temp_img_keys = explode(" ", trim($zp_showimage_keys) ); |
| 862 |
$zp_temp_img_keys_count = count($zp_temp_img_keys); |
| 863 |
$zp_temp_img_ph = array_fill(0, $zp_temp_img_keys_count, "s"); |
| 864 |
foreach ( $zp_temp_img_ph as $i => $ii ) |
| 865 |
$zp_temp_img_ph[$i] = '\'%'.($i+1).'$s\''; |
| 866 |
$zp_temp_img_ph = implode(",", $zp_temp_img_ph); |
| 867 |
|
| 868 |
// 7.4: PCP doesn't properly support IN(), so ... |
| 869 |
$wpdb->zp_img_map_keys = $zp_temp_img_ph; |
| 870 |
|
| 871 |
$zp_images = $wpdb->get_results( |
| 872 |
$wpdb->prepare( |
| 873 |
" |
| 874 |
SELECT * FROM `".$wpdb->prefix."zotpress_zoteroItemImages` |
| 875 |
WHERE `item_key` IN ({$wpdb->zp_img_map_keys}) |
| 876 |
", |
| 877 |
$zp_temp_img_keys |
| 878 |
) |
| 879 |
); |
| 880 |
|
| 881 |
if ( count($zp_images) > 0 ) |
| 882 |
{ |
| 883 |
foreach ( $zp_images as $image ) |
| 884 |
{ |
| 885 |
$zp_thumbnail = wp_get_attachment_image_src($image->image); |
| 886 |
|
| 887 |
foreach ( $zp_all_the_data as $id => $data ) |
| 888 |
{ |
| 889 |
if ( $data->key == $image->item_key) |
| 890 |
{ |
| 891 |
$zp_all_the_data[$id]->image = $zp_thumbnail; |
| 892 |
|
| 893 |
// URL Wrap for images |
| 894 |
if ( $zpr["urlwrap"] && $zpr["urlwrap"] == "image" && $zp_all_the_data[$id]->data->url != "" ) |
| 895 |
{ |
| 896 |
// Get rid of default URL listing |
| 897 |
// TODO: Does this account for all citation styles? |
| 898 |
$zp_all_the_data[$id]->bib = str_replace( htmlentities($zp_all_the_data[$id]->data->url), "", $zp_all_the_data[$id]->bib ); |
| 899 |
$zp_all_the_data[$id]->bib = str_replace( " Retrieved from ", "", $zp_all_the_data[$id]->bib ); |
| 900 |
$zp_all_the_data[$id]->bib = str_replace( " Available from: ", "", $zp_all_the_data[$id]->bib ); |
| 901 |
} |
| 902 |
} |
| 903 |
} |
| 904 |
} |
| 905 |
} // If images found in zpdb |
| 906 |
|
| 907 |
// Check open lib next |
| 908 |
// REVIEW: Will break if Open Library is down! |
| 909 |
// 7.4.3: Added fixes via André Lambelet, e.g., https, headers |
| 910 |
if ( $zpr["showimage"] === "openlib" ) |
| 911 |
{ |
| 912 |
$zp_showimage_keys = explode( ",", $zp_showimage_keys ); |
| 913 |
|
| 914 |
foreach ( $zp_all_the_data as $id => $data ) |
| 915 |
{ |
| 916 |
if ( ! in_array( $data->key, $zp_showimage_keys ) |
| 917 |
&& ( isset($data->data->ISBN) && $data->data->ISBN != "" ) ) |
| 918 |
{ |
| 919 |
$openlib_url = "https://covers.openlibrary.org/b/isbn/".$data->data->ISBN."-M.jpg"; |
| 920 |
|
| 921 |
// First, get the headers |
| 922 |
$openlib_headers = @get_headers( $openlib_url ); |
| 923 |
|
| 924 |
// And make sure Open Library / the source is online |
| 925 |
// if ( $openlib_headers[0] == "HTTP/1.1 302 Found" ) |
| 926 |
$openlib_status = isset($openlib_headers[0]) ? $openlib_headers[0] : ''; |
| 927 |
$openlib_ctype = ''; |
| 928 |
foreach ( $openlib_headers as $h ) { |
| 929 |
if ( stripos( $h, 'content-type:' ) === 0 ) { |
| 930 |
$openlib_ctype = strtolower( $h ); |
| 931 |
break; |
| 932 |
} |
| 933 |
} |
| 934 |
if ( ( strpos($openlib_status, '200') !== false && strpos($openlib_ctype, 'image/jpeg') !== false ) |
| 935 |
|| strpos($openlib_status, '302') !== false ) |
| 936 |
{ |
| 937 |
$zp_all_the_data[$id]->image = array( $openlib_url ); |
| 938 |
|
| 939 |
// URL Wrap for images |
| 940 |
if ( $zpr["urlwrap"] |
| 941 |
&& $zpr["urlwrap"] == 'image' |
| 942 |
&& $zp_all_the_data[$id]->data->url != '' ) |
| 943 |
{ |
| 944 |
// Get rid of default URL listing |
| 945 |
// TODO: Does this account for all citation styles? |
| 946 |
$zp_all_the_data[$id]->bib = str_replace( htmlentities($zp_all_the_data[$id]->data->url), "", $zp_all_the_data[$id]->bib ); |
| 947 |
$zp_all_the_data[$id]->bib = str_replace( " Retrieved from ", "", $zp_all_the_data[$id]->bib ); |
| 948 |
$zp_all_the_data[$id]->bib = str_replace( " Available from: ", "", $zp_all_the_data[$id]->bib ); |
| 949 |
} |
| 950 |
} |
| 951 |
} |
| 952 |
} |
| 953 |
} |
| 954 |
} // showimage |
| 955 |
|
| 956 |
// 7.4: Major change to passing and parsing bib HTML |
| 957 |
// 7.4 Update: There's a 30 second timeout without the cache with downloads ... |
| 958 |
// TODO: Perhaps cache the download requests and deal with them separately |
| 959 |
foreach ( $zp_all_the_data as $id => $data ) |
| 960 |
{ |
| 961 |
// 7.4 Update: Trying to avoid errors ... |
| 962 |
if ( isset($zp_all_the_data[$id]->bib) ) |
| 963 |
$zp_all_the_data[$id]->bib = esc_html($zp_all_the_data[$id]->bib); |
| 964 |
|
| 965 |
// 7.4: Abstract breaking when unicode exists |
| 966 |
// if ( isset($zp_all_the_data[$id]->data->abstractNote) ) |
| 967 |
// $zp_all_the_data[$id]->data->abstractNote = mb_convert_encoding($zp_all_the_data[$id]->data->abstractNote, 'UTF-8', 'UCS-2BE'); |
| 968 |
// 7.4.1: Now appears in another language sometimes ... fix by Jeremy Varnham (@jvarn13) |
| 969 |
if ( isset($zp_all_the_data[$id]->data->abstractNote) ) |
| 970 |
$zp_all_the_data[$id]->data->abstractNote = esc_html($zp_all_the_data[$id]->data->abstractNote); |
| 971 |
} |
| 972 |
|
| 973 |
// Re-sort with order of entry if bib and default sort |
| 974 |
if ( $zpr["item_type"] == "items" |
| 975 |
&& $zpr["sortby"] == "default" |
| 976 |
&& count($zpr["item_keys_order"]) > 0 ) |
| 977 |
{ |
| 978 |
$temp_arr = array(); |
| 979 |
|
| 980 |
foreach ( $zpr["item_keys_order"] as $temp_key ) |
| 981 |
{ |
| 982 |
foreach ( $zp_all_the_data as $temp_data ) |
| 983 |
{ |
| 984 |
if ( $temp_data->key == $temp_key ) |
| 985 |
$temp_arr[] = $temp_data; |
| 986 |
} |
| 987 |
} |
| 988 |
|
| 989 |
$zp_all_the_data = $temp_arr; |
| 990 |
} |
| 991 |
|
| 992 |
|
| 993 |
// Remove extra meta data: |
| 994 |
foreach ( $zp_all_the_data as $id => $data ) |
| 995 |
{ |
| 996 |
unset( $zp_all_the_data[$id]->meta->createdByUser ); |
| 997 |
} |
| 998 |
|
| 999 |
} // if there's data (more than 0) |
| 1000 |
} |
| 1001 |
|
| 1002 |
else // No results |
| 1003 |
{ |
| 1004 |
// $zp_all_the_data = ""; // Necessary? |
| 1005 |
} |
| 1006 |
|
| 1007 |
|
| 1008 |
|
| 1009 |
// +----------------------------+ |
| 1010 |
// | Finish and output the data | |
| 1011 |
// +----------------------------+ |
| 1012 |
|
| 1013 |
unset($zp_import_contents); |
| 1014 |
unset($zp_import_url); |
| 1015 |
unset($zp_xml); |
| 1016 |
unset($api_user_id); |
| 1017 |
unset($zp_account); |
| 1018 |
|
| 1019 |
$wpdb->flush(); |
| 1020 |
|
| 1021 |
// Deal with cache scenarios: |
| 1022 |
// 1. Used the cache |
| 1023 |
// 2. Didn't check (why???) |
| 1024 |
// TEST: Why are these checks needed? There's no "else" ... removing for now |
| 1025 |
if ( ( $checkcache && $zp_usecache ) |
| 1026 |
|| ( ! $checkcache ) ) |
| 1027 |
{ |
| 1028 |
$zp_output = ''; |
| 1029 |
|
| 1030 |
if ( $zp_usecache ) |
| 1031 |
{ |
| 1032 |
// Indicate new (just cached) or cached used: |
| 1033 |
$zp_request_meta['used_cache'] = true; |
| 1034 |
} |
| 1035 |
|
| 1036 |
if ( count($zp_all_the_data) > 0 |
| 1037 |
&& $zp_all_the_data != "" ) |
| 1038 |
{ |
| 1039 |
$zp_json_encoded = wp_json_encode( |
| 1040 |
array ( |
| 1041 |
"status" => "success", |
| 1042 |
"updateneeded" => $zp_updateneeded, |
| 1043 |
"instance" => $zpr["instance_id"], |
| 1044 |
"meta" => $zp_request_meta, |
| 1045 |
"data" => $zp_all_the_data |
| 1046 |
) |
| 1047 |
); |
| 1048 |
|
| 1049 |
if ( $is_ajax ) // JS: |
| 1050 |
{ |
| 1051 |
// echo $zp_json_encoded; |
| 1052 |
echo wp_kses($zp_json_encoded, |
| 1053 |
array( |
| 1054 |
'p' => array(), |
| 1055 |
'i' => array(), |
| 1056 |
'b' => array(), |
| 1057 |
'em' => array(), |
| 1058 |
'strong' => array(), |
| 1059 |
'div' => array( |
| 1060 |
'class' => array(), |
| 1061 |
'style' => array() |
| 1062 |
), |
| 1063 |
) |
| 1064 |
); |
| 1065 |
|
| 1066 |
exit(); // REVIEW: Causing to break if error |
| 1067 |
} |
| 1068 |
else // PHP: |
| 1069 |
{ |
| 1070 |
// TEST: Is this right? |
| 1071 |
$zp_output = "\t\t\t\t"; |
| 1072 |
|
| 1073 |
if ( $zp_updateneeded ) |
| 1074 |
$zp_output .= '<span class="ZP_UPDATENEEDED ZP_ATTR">true</span>'; |
| 1075 |
$zp_output .= '<span class="ZP_CACHETIMER ZP_ATTR">'.get_option("Zotpress_DefaultCacheTimer").'</span>'; |
| 1076 |
|
| 1077 |
// $zp_output .= '<span class="ZP_USED_CACHE ZP_ATTR">true</span>'; |
| 1078 |
$zp_output .= '<span class="ZP_JSON ZP_ATTR">'.rawurlencode($zp_json_encoded).'</span>'; |
| 1079 |
$zp_output .= "\n\n"; |
| 1080 |
|
| 1081 |
foreach ( $zp_all_the_data as $zp_citation ) |
| 1082 |
{ |
| 1083 |
// QUESTION: Why is it a string? |
| 1084 |
// $zp_citation = json_decode($zp_citation); |
| 1085 |
|
| 1086 |
$zp_output .= "\t\t\t\t"; |
| 1087 |
$zp_output .= '<div id="zp-ID-'.$post->ID.'-'.$zp_citation->library->id.'-'.$zp_citation->key.'"'; |
| 1088 |
|
| 1089 |
$tempItemDate = "0000-00-00"; |
| 1090 |
$tempItemYear = "0000"; |
| 1091 |
$tempItemType = $zp_citation->data->itemType; |
| 1092 |
if ( property_exists($zp_citation->meta, "parsedDate")) { |
| 1093 |
$tempItemDate = $zp_citation->meta->parsedDate; |
| 1094 |
$tempItemYear = substr($zp_citation->meta->parsedDate, 0, 4); |
| 1095 |
} |
| 1096 |
|
| 1097 |
$tempAuthor = ""; |
| 1098 |
if ( property_exists($zp_citation->meta, "creatorSummary")) |
| 1099 |
$tempAuthor = str_replace(' ', '-', $zp_citation->meta->creatorSummary); |
| 1100 |
|
| 1101 |
$zp_output .= " data-zp-author-date='".$tempAuthor."-".$tempItemDate."'"; |
| 1102 |
$zp_output .= " data-zp-date-author='".$tempItemDate."-".$tempAuthor."'"; |
| 1103 |
$zp_output .= " data-zp-date='".$tempItemDate."'"; |
| 1104 |
$zp_output .= " data-zp-year='".$tempItemYear."'"; |
| 1105 |
$zp_output .= " data-zp-itemtype='".$tempItemType."'"; |
| 1106 |
$zp_output .= ' class="zp-Entry zpSearchResultsItem">'; |
| 1107 |
$zp_output .= "\n"; |
| 1108 |
// 7.4: Major change to passing and parsing bib HTML |
| 1109 |
// $zp_output .= $zp_citation->bib; |
| 1110 |
$zp_output .= html_entity_decode($zp_citation->bib); |
| 1111 |
$zp_output .= "\n\t\t\t\t"; |
| 1112 |
$zp_output .= '</div><!-- .zp-Entry .zpSearchResultsItem -->'; |
| 1113 |
} |
| 1114 |
return $zp_output; |
| 1115 |
} |
| 1116 |
} |
| 1117 |
else // No data or error: |
| 1118 |
{ |
| 1119 |
if ( ! isset($zpr["instance_id"]) ) |
| 1120 |
$zpr["instance_id"] = false; |
| 1121 |
|
| 1122 |
// Indicate problem or no cache: |
| 1123 |
$zp_request_meta['used_cache'] = false; |
| 1124 |
|
| 1125 |
if ( $is_ajax ) |
| 1126 |
if ( $zp_error ) |
| 1127 |
$zp_output = wp_json_encode( |
| 1128 |
array ( |
| 1129 |
"status" => "error", |
| 1130 |
"instance" => $zpr["instance_id"], |
| 1131 |
"meta" => $zp_request_meta, |
| 1132 |
"data" => $zp_error |
| 1133 |
) |
| 1134 |
); |
| 1135 |
else // catchall, likely just no items for request |
| 1136 |
$zp_output = wp_json_encode( |
| 1137 |
array ( |
| 1138 |
"status" => "empty", |
| 1139 |
"instance" => $zpr["instance_id"], |
| 1140 |
"meta" => $zp_request_meta, |
| 1141 |
"data" => "0" |
| 1142 |
) |
| 1143 |
); |
| 1144 |
|
| 1145 |
// echo $zp_output; |
| 1146 |
echo wp_kses($zp_output, |
| 1147 |
array( |
| 1148 |
'p' => array(), |
| 1149 |
'i' => array(), |
| 1150 |
'b' => array(), |
| 1151 |
'em' => array(), |
| 1152 |
'strong' => array(), |
| 1153 |
'div' => array( |
| 1154 |
'id' => array(), |
| 1155 |
'class' => array(), |
| 1156 |
'style' => array() |
| 1157 |
), |
| 1158 |
) |
| 1159 |
); |
| 1160 |
|
| 1161 |
if ( $is_ajax ) |
| 1162 |
exit(); // REVIEW: Causing to break if error |
| 1163 |
} |
| 1164 |
} |
| 1165 |
} |
| 1166 |
add_action( 'wp_ajax_zpRetrieveViaShortcode', 'Zotpress_shortcode_request' ); |
| 1167 |
add_action( 'wp_ajax_nopriv_zpRetrieveViaShortcode', 'Zotpress_shortcode_request' ); |
| 1168 |
|
| 1169 |
?> |