| [ Index ] |
PHP Cross Reference of YOURLS |
[Summary view] [Print] [Text view]
1 <?php 2 /* 3 * Functions relative to short URLs: adding, editing, etc 4 * (either proper short URLs ("http://sho.rt/abc") or "keywords" (the "abc" part) 5 */ 6 7 8 /** 9 * Add a new link in the DB, either with custom keyword, or find one 10 * 11 * The return array will contain at least the following keys: 12 * status: string, 'success' or 'fail' 13 * message: string, a descriptive localized message of what happened in any case 14 * code: string, a short descriptivish and untranslated message describing what happened 15 * errorCode: string, a HTTP status code 16 * statusCode: string, a HTTP status code 17 * Depending on the operation, it will contain any of the following keys: 18 * url: array, the short URL creation information, with keys: 'keyword', 'url', 'title', 'date', 'ip', 'clicks' 19 * title: string, the URL title 20 * shorturl: string, the proper short URL in full (eg 'http://sho.rt/abc') 21 * html: string, the HTML part used by the ajax to update the page display if any 22 * 23 * For compatibility with early consumers and third parties, when people asked for various data and data formats 24 * before the internal API was really structured, the return array now collects several redundant information. 25 * 26 * @param string $url URL to shorten 27 * @param string $keyword optional "keyword" 28 * @param string $title option title 29 * @param int $row_id used to form unique IDs in the generated HTML 30 * @return array array with error/success state and short URL information 31 */ 32 function yourls_add_new_link( $url, $keyword = '', $title = '', $row_id = 1 ) { 33 // Allow plugins to short-circuit the whole function 34 $pre = yourls_apply_filter( 'shunt_add_new_link', false, $url, $keyword, $title ); 35 if ( false !== $pre ) { 36 return $pre; 37 } 38 39 /** 40 * The result array. 41 */ 42 $return = [ 43 // Always present : 44 'status' => '', 45 'code' => '', 46 'message' => '', 47 'errorCode' => '', 48 'statusCode' => '', 49 ]; 50 51 // Sanitize URL 52 $url = yourls_sanitize_url( $url ); 53 if ( !$url || $url == 'http://' || $url == 'https://' ) { 54 $return['status'] = 'fail'; 55 $return['code'] = 'error:nourl'; 56 $return['message'] = yourls__( 'Missing or malformed URL' ); 57 $return['errorCode'] = $return['statusCode'] = '400'; // 400 Bad Request 58 59 return yourls_apply_filter( 'add_new_link_fail_nourl', $return, $url, $keyword, $title ); 60 } 61 62 // Prevent DB flood 63 $ip = yourls_get_IP(); 64 yourls_check_IP_flood( $ip ); 65 66 // Prevent internal redirection loops: cannot shorten a shortened URL 67 if (yourls_is_shorturl($url)) { 68 $return['status'] = 'fail'; 69 $return['code'] = 'error:noloop'; 70 $return['message'] = yourls__( 'URL is a short URL' ); 71 $return['errorCode'] = $return['statusCode'] = '400'; // 400 Bad Request 72 return yourls_apply_filter( 'add_new_link_fail_noloop', $return, $url, $keyword, $title ); 73 } 74 75 yourls_do_action( 'pre_add_new_link', $url, $keyword, $title ); 76 77 // Check if URL was already stored and we don't accept duplicates 78 if ( !yourls_allow_duplicate_longurls() && ($url_exists = yourls_long_url_exists( $url )) ) { 79 yourls_do_action( 'add_new_link_already_stored', $url, $keyword, $title ); 80 81 $return['status'] = 'fail'; 82 $return['code'] = 'error:url'; 83 $return['url'] = array( 'keyword' => $url_exists->keyword, 'url' => $url, 'title' => $url_exists->title, 'date' => $url_exists->timestamp, 'ip' => $url_exists->ip, 'clicks' => $url_exists->clicks ); 84 $return['message'] = /* //translators: eg "http://someurl/ already exists (short URL: sho.rt/abc)" */ yourls_s('%s already exists in database (short URL: %s)', 85 yourls_trim_long_string($url), preg_replace('!https?://!', '', yourls_get_yourls_site()) . '/'. $url_exists->keyword ); 86 $return['title'] = $url_exists->title; 87 $return['shorturl'] = yourls_link($url_exists->keyword); 88 $return['errorCode'] = $return['statusCode'] = '400'; // 400 Bad Request 89 90 return yourls_apply_filter( 'add_new_link_already_stored_filter', $return, $url, $keyword, $title ); 91 } 92 93 // Sanitize provided title, or fetch one 94 if( isset( $title ) && !empty( $title ) ) { 95 $title = yourls_sanitize_title( $title ); 96 } else { 97 $title = yourls_get_remote_title( $url ); 98 } 99 $title = yourls_apply_filter( 'add_new_title', $title, $url, $keyword ); 100 101 // Custom keyword provided : sanitize and make sure it's free 102 if ($keyword) { 103 yourls_do_action( 'add_new_link_custom_keyword', $url, $keyword, $title ); 104 105 $keyword = yourls_sanitize_keyword( $keyword, true ); 106 $keyword = yourls_apply_filter( 'custom_keyword', $keyword, $url, $title ); 107 108 if ( !yourls_keyword_is_free( $keyword ) ) { 109 // This shorturl either reserved or taken already 110 $return['status'] = 'fail'; 111 $return['code'] = 'error:keyword'; 112 $return['message'] = yourls_s( 'Short URL %s already exists in database or is reserved', $keyword ); 113 $return['errorCode'] = $return['statusCode'] = '400'; // 400 Bad Request 114 115 return yourls_apply_filter( 'add_new_link_keyword_exists', $return, $url, $keyword, $title ); 116 } 117 118 // Create random keyword 119 } else { 120 yourls_do_action( 'add_new_link_create_keyword', $url, $keyword, $title ); 121 122 $id = yourls_get_next_decimal(); 123 124 do { 125 $keyword = yourls_int2string( $id ); 126 $keyword = yourls_apply_filter( 'random_keyword', $keyword, $url, $title ); 127 $id++; 128 } while ( !yourls_keyword_is_free($keyword) ); 129 130 yourls_update_next_decimal($id); 131 } 132 133 // We should be all set now. Store the short URL ! 134 135 $timestamp = date( 'Y-m-d H:i:s' ); 136 137 try { 138 if (yourls_insert_link_in_db( $url, $keyword, $title )){ 139 // everything ok, populate needed vars 140 $return['url'] = array('keyword' => $keyword, 'url' => $url, 'title' => $title, 'date' => $timestamp, 'ip' => $ip ); 141 $return['status'] = 'success'; 142 $return['message'] = /* //translators: eg "http://someurl/ added to DB" */ yourls_s( '%s added to database', yourls_trim_long_string( $url ) ); 143 $return['title'] = $title; 144 $return['html'] = yourls_table_add_row( $keyword, $url, $title, $ip, 0, time(), $row_id ); 145 $return['shorturl'] = yourls_link($keyword); 146 $return['statusCode'] = '200'; // 200 OK 147 } else { 148 // unknown database error, couldn't store result 149 $return['status'] = 'fail'; 150 $return['code'] = 'error:db'; 151 $return['message'] = yourls_s( 'Error saving url to database' ); 152 $return['errorCode'] = $return['statusCode'] = '500'; // 500 Internal Server Error 153 } 154 } catch (Exception $e) { 155 // Keyword supposed to be free but the INSERT caused an exception: most likely we're facing a 156 // concurrency problem. See Issue 2538. 157 $return['status'] = 'fail'; 158 $return['code'] = 'error:concurrency'; 159 $return['message'] = $e->getMessage(); 160 $return['errorCode'] = $return['statusCode'] = '503'; // 503 Service Unavailable 161 } 162 163 yourls_do_action( 'post_add_new_link', $url, $keyword, $title, $return ); 164 165 return yourls_apply_filter( 'add_new_link', $return, $url, $keyword, $title ); 166 } 167 /** 168 * Determine the allowed character set in short URLs 169 * 170 * @return string Acceptable charset for short URLS keywords 171 */ 172 function yourls_get_shorturl_charset() { 173 if ( defined( 'YOURLS_URL_CONVERT' ) && in_array( YOURLS_URL_CONVERT, [ 62, 64 ] ) ) { 174 $charset = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; 175 } 176 else { 177 // defined to 36, or wrongly defined 178 $charset = '0123456789abcdefghijklmnopqrstuvwxyz'; 179 } 180 181 return yourls_apply_filter( 'get_shorturl_charset', $charset ); 182 } 183 184 /** 185 * Is a URL a short URL? Accept either 'http://sho.rt/abc' or 'abc' 186 * 187 * @param string $shorturl short URL 188 * @return bool true if registered short URL, false otherwise 189 */ 190 function yourls_is_shorturl( $shorturl ) { 191 // TODO: make sure this function evolves with the feature set. 192 193 $is_short = false; 194 195 // Is $shorturl a URL (http://sho.rt/abc) or a keyword (abc) ? 196 if( yourls_get_protocol( $shorturl ) ) { 197 $keyword = yourls_get_relative_url( $shorturl ); 198 } else { 199 $keyword = $shorturl; 200 } 201 202 // Check if it's a valid && used keyword 203 if( $keyword && $keyword == yourls_sanitize_keyword( $keyword ) && yourls_keyword_is_taken( $keyword ) ) { 204 $is_short = true; 205 } 206 207 return yourls_apply_filter( 'is_shorturl', $is_short, $shorturl ); 208 } 209 210 /** 211 * Get the list of reserved keywords for URLs. 212 * 213 * @return array Array of reserved keywords 214 */ 215 function yourls_get_reserved_URL() { 216 global $yourls_reserved_URL; 217 if ( ! isset( $yourls_reserved_URL ) || ! is_array( $yourls_reserved_URL ) ) { 218 return array(); 219 } 220 221 return $yourls_reserved_URL; 222 } 223 224 /** 225 * Check to see if a given keyword is reserved (ie reserved URL or an existing page). Returns bool 226 * 227 * @param string $keyword Short URL keyword 228 * @return bool True if keyword reserved, false if free to be used 229 */ 230 function yourls_keyword_is_reserved( $keyword ) { 231 $keyword = yourls_sanitize_keyword( $keyword ); 232 $reserved = false; 233 234 if ( in_array( $keyword, yourls_get_reserved_URL() ) 235 or yourls_is_page($keyword) 236 or is_dir( YOURLS_ABSPATH ."/$keyword" ) 237 ) 238 $reserved = true; 239 240 return yourls_apply_filter( 'keyword_is_reserved', $reserved, $keyword ); 241 } 242 243 /** 244 * Delete a link in the DB 245 * 246 * @param string $keyword Short URL keyword 247 * @return int Number of links deleted 248 */ 249 function yourls_delete_link_by_keyword( $keyword ) { 250 // Allow plugins to short-circuit the whole function 251 $pre = yourls_apply_filter( 'shunt_delete_link_by_keyword', null, $keyword ); 252 if ( null !== $pre ) { 253 return $pre; 254 } 255 256 $table = YOURLS_DB_TABLE_URL; 257 $keyword = yourls_sanitize_keyword($keyword); 258 $ydb = yourls_get_db(); 259 $delete = $ydb->fetchAffected("DELETE FROM `$table` WHERE `keyword` = :keyword", array('keyword' => $keyword)); 260 $ydb->delete_infos($keyword); // Clear the cache. 261 yourls_do_action( 'delete_link', $keyword, $delete ); 262 return $delete; 263 } 264 265 /** 266 * SQL query to insert a new link in the DB. Returns boolean for success or failure of the inserting 267 * 268 * @param string $url 269 * @param string $keyword 270 * @param string $title 271 * @return bool true if insert succeeded, false if failed 272 */ 273 function yourls_insert_link_in_db($url, $keyword, $title = '' ) { 274 $url = yourls_sanitize_url($url); 275 $keyword = yourls_sanitize_keyword($keyword); 276 $title = yourls_sanitize_title($title); 277 $timestamp = date('Y-m-d H:i:s'); 278 $ip = yourls_get_IP(); 279 280 $table = YOURLS_DB_TABLE_URL; 281 $binds = array( 282 'keyword' => $keyword, 283 'url' => $url, 284 'title' => $title, 285 'timestamp' => $timestamp, 286 'ip' => $ip, 287 ); 288 $ydb = yourls_get_db(); 289 $insert = $ydb->fetchAffected("INSERT INTO `$table` (`keyword`, `url`, `title`, `timestamp`, `ip`, `clicks`) VALUES(:keyword, :url, :title, :timestamp, :ip, 0);", $binds); 290 291 if ( $insert ) { 292 $infos = $binds; 293 $infos['clicks'] = 0; 294 $ydb->set_infos($keyword, $infos); 295 } 296 297 yourls_do_action( 'insert_link', (bool)$insert, $url, $keyword, $title, $timestamp, $ip ); 298 299 return (bool)$insert; 300 } 301 302 /** 303 * Check if a long URL already exists in the DB. Return NULL (doesn't exist) or an object with URL informations. 304 * 305 * This function supersedes function yourls_url_exists(), deprecated in 1.7.10, with a better naming. 306 * 307 * @since 1.7.10 308 * @param string $url URL to check if already shortened 309 * @return mixed NULL if does not already exist in DB, or object with URL information as properties (eg keyword, url, title, ...) 310 */ 311 function yourls_long_url_exists( $url ) { 312 // Allow plugins to short-circuit the whole function 313 $pre = yourls_apply_filter( 'shunt_url_exists', false, $url ); 314 if ( false !== $pre ) { 315 return $pre; 316 } 317 318 $table = YOURLS_DB_TABLE_URL; 319 $url = yourls_sanitize_url($url); 320 $url_exists = yourls_get_db()->fetchObject("SELECT * FROM `$table` WHERE `url` = :url", array('url'=>$url)); 321 322 if ($url_exists === false) { 323 $url_exists = NULL; 324 } 325 326 return yourls_apply_filter( 'url_exists', $url_exists, $url ); 327 } 328 329 /** 330 * Edit a link 331 * 332 * @param string $url 333 * @param string $keyword 334 * @param string $newkeyword 335 * @param string $title 336 * @return array Result of the edit and link information if successful 337 */ 338 function yourls_edit_link($url, $keyword, $newkeyword='', $title='' ) { 339 // Allow plugins to short-circuit the whole function 340 $pre = yourls_apply_filter( 'shunt_edit_link', null, $keyword, $url, $keyword, $newkeyword, $title ); 341 if ( null !== $pre ) 342 return $pre; 343 344 $ydb = yourls_get_db(); 345 346 $table = YOURLS_DB_TABLE_URL; 347 $url = yourls_sanitize_url($url); 348 $keyword = yourls_sanitize_keyword($keyword); 349 $title = yourls_sanitize_title($title); 350 $newkeyword = yourls_sanitize_keyword($newkeyword, true); 351 352 if(!$url OR !$newkeyword) { 353 $return['status'] = 'fail'; 354 $return['message'] = yourls__( 'Long URL or Short URL cannot be blank' ); 355 return yourls_apply_filter( 'edit_link', $return, $url, $keyword, $newkeyword, $title ); 356 } 357 358 $old_url = $ydb->fetchValue("SELECT `url` FROM `$table` WHERE `keyword` = :keyword", array('keyword' => $keyword)); 359 360 // Check if new URL is not here already 361 if ( $old_url != $url && !yourls_allow_duplicate_longurls() ) { 362 $new_url_already_there = intval($ydb->fetchValue("SELECT COUNT(keyword) FROM `$table` WHERE `url` = :url;", array('url' => $url))); 363 } else { 364 $new_url_already_there = false; 365 } 366 367 // Check if the new keyword is not here already 368 if ( $newkeyword != $keyword ) { 369 $keyword_is_ok = yourls_keyword_is_free( $newkeyword ); 370 } else { 371 $keyword_is_ok = true; 372 } 373 374 yourls_do_action( 'pre_edit_link', $url, $keyword, $newkeyword, $new_url_already_there, $keyword_is_ok ); 375 376 // All clear, update 377 if ( ( !$new_url_already_there || yourls_allow_duplicate_longurls() ) && $keyword_is_ok ) { 378 $sql = "UPDATE `$table` SET `url` = :url, `keyword` = :newkeyword, `title` = :title WHERE `keyword` = :keyword"; 379 $binds = array('url' => $url, 'newkeyword' => $newkeyword, 'title' => $title, 'keyword' => $keyword); 380 $update_url = $ydb->fetchAffected($sql, $binds); 381 if( $update_url ) { 382 $return['url'] = array( 'keyword' => $newkeyword, 383 'shorturl' => yourls_link($newkeyword), 384 'url' => yourls_esc_url($url), 385 'display_url' => yourls_esc_html(yourls_trim_long_string($url)), 386 'title' => yourls_esc_attr($title), 387 'display_title' => yourls_esc_html(yourls_trim_long_string( $title )) 388 ); 389 $return['status'] = 'success'; 390 $return['message'] = yourls__( 'Link updated in database' ); 391 $ydb->update_infos_if_exists($newkeyword, array('url' => $url, 'title' => $title)); // Clear the cache. 392 if ($keyword != $newkeyword) { 393 $ydb->delete_infos($keyword); // Clear the cache on the old keyword. 394 } 395 } else { 396 $return['status'] = 'fail'; 397 $return['message'] = /* //translators: "Error updating http://someurl/ (Shorturl: http://sho.rt/blah)" */ yourls_s( 'Error updating %s (Short URL: %s)', yourls_esc_html(yourls_trim_long_string($url)), $keyword ) ; 398 } 399 400 // Nope 401 } else { 402 $return['status'] = 'fail'; 403 $return['message'] = yourls__( 'URL or keyword already exists in database' ); 404 } 405 406 return yourls_apply_filter( 'edit_link', $return, $url, $keyword, $newkeyword, $title, $new_url_already_there, $keyword_is_ok ); 407 } 408 409 /** 410 * Update a title link (no checks for duplicates etc..) 411 * 412 * @param string $keyword 413 * @param string $title 414 * @return int number of rows updated 415 */ 416 function yourls_edit_link_title( $keyword, $title ) { 417 // Allow plugins to short-circuit the whole function 418 $pre = yourls_apply_filter( 'shunt_edit_link_title', null, $keyword, $title ); 419 if ( null !== $pre ) { 420 return $pre; 421 } 422 423 $keyword = yourls_sanitize_keyword( $keyword ); 424 $title = yourls_sanitize_title( $title ); 425 426 $table = YOURLS_DB_TABLE_URL; 427 $ydb = yourls_get_db(); 428 $update = $ydb->fetchAffected("UPDATE `$table` SET `title` = :title WHERE `keyword` = :keyword;", array('title' => $title, 'keyword' => $keyword)); 429 430 if ( $update ) { 431 $ydb->update_infos_if_exists( $keyword, array('title' => $title) ); 432 } 433 434 return $update; 435 } 436 437 /** 438 * Check if keyword id is free (ie not already taken, and not reserved). Return bool. 439 * 440 * @param string $keyword short URL keyword 441 * @return bool true if keyword is taken (ie there is a short URL for it), false otherwise 442 */ 443 function yourls_keyword_is_free( $keyword ) { 444 $free = true; 445 if ( yourls_keyword_is_reserved( $keyword ) or yourls_keyword_is_taken( $keyword, false ) ) { 446 $free = false; 447 } 448 449 return yourls_apply_filter( 'keyword_is_free', $free, $keyword ); 450 } 451 452 /** 453 * Check if a keyword matches a "page" 454 * 455 * @see https://docs.yourls.org/guide/extend/pages.html 456 * @since 1.7.10 457 * @param string $keyword Short URL $keyword 458 * @return bool true if is page, false otherwise 459 */ 460 function yourls_is_page($keyword) { 461 return yourls_apply_filter( 'is_page', file_exists( YOURLS_PAGEDIR . "/$keyword.php" ) ); 462 } 463 464 /** 465 * Check if a keyword is taken (ie there is already a short URL with this id). Return bool. 466 * 467 */ 468 /** 469 * Check if a keyword is taken (ie there is already a short URL with this id). Return bool. 470 * 471 * @param string $keyword short URL keyword 472 * @param bool $use_cache optional, default true: do we want to use what is cached in memory, if any, or force a new SQL query 473 * @return bool true if keyword is taken (ie there is a short URL for it), false otherwise 474 */ 475 function yourls_keyword_is_taken( $keyword, $use_cache = true ) { 476 // Allow plugins to short-circuit the whole function 477 $pre = yourls_apply_filter( 'shunt_keyword_is_taken', false, $keyword ); 478 if ( false !== $pre ) { 479 return $pre; 480 } 481 482 $taken = false; 483 // To check if a keyword is already associated with a short URL, we fetch all info matching that keyword. This 484 // will save a query in case of a redirection in yourls-go.php because info will be cached 485 if ( yourls_get_keyword_infos($keyword, $use_cache) ) { 486 $taken = true; 487 } 488 489 return yourls_apply_filter( 'keyword_is_taken', $taken, $keyword ); 490 } 491 492 /** 493 * Return array of all information associated with keyword. Returns false if keyword not found. Set optional $use_cache to false to force fetching from DB 494 * 495 * Sincere apologies to native English speakers, we are aware that the plural of 'info' is actually 'info', not 'infos'. 496 * This function yourls_get_keyword_infos() returns all information, while function yourls_get_keyword_info() (no 's') return only 497 * one information. Blame YOURLS contributors whose mother tongue is not English :) 498 * 499 * @since 1.4 500 * @param string $keyword Short URL keyword 501 * @param bool $use_cache Default true, set to false to force fetching from DB 502 * @return false|object false if not found, object with URL properties if found 503 */ 504 function yourls_get_keyword_infos( $keyword, $use_cache = true ) { 505 $ydb = yourls_get_db(); 506 $keyword = yourls_sanitize_keyword( $keyword ); 507 508 yourls_do_action( 'pre_get_keyword', $keyword, $use_cache ); 509 510 if( $ydb->has_infos($keyword) && $use_cache === true ) { 511 return yourls_apply_filter( 'get_keyword_infos', $ydb->get_infos($keyword), $keyword ); 512 } 513 514 yourls_do_action( 'get_keyword_not_cached', $keyword ); 515 516 $table = YOURLS_DB_TABLE_URL; 517 $infos = $ydb->fetchObject("SELECT * FROM `$table` WHERE `keyword` = :keyword", array('keyword' => $keyword)); 518 519 if( $infos ) { 520 $infos = (array)$infos; 521 $ydb->set_infos($keyword, $infos); 522 } else { 523 // is NULL if not found 524 $infos = false; 525 $ydb->set_infos($keyword, false); 526 } 527 528 return yourls_apply_filter( 'get_keyword_infos', $infos, $keyword ); 529 } 530 531 /** 532 * Return information associated with a keyword (eg clicks, URL, title...). Optional $notfound = string default message if nothing found 533 * 534 * @param string $keyword Short URL keyword 535 * @param string $field Field to return (eg 'url', 'title', 'ip', 'clicks', 'timestamp', 'keyword') 536 * @param false|string $notfound Optional string to return if keyword not found 537 * @return mixed|string 538 */ 539 function yourls_get_keyword_info($keyword, $field, $notfound = false ) { 540 541 // Allow plugins to short-circuit the whole function 542 $pre = yourls_apply_filter( 'shunt_get_keyword_info', false, $keyword, $field, $notfound ); 543 if ( false !== $pre ) 544 return $pre; 545 546 $keyword = yourls_sanitize_keyword( $keyword ); 547 $infos = yourls_get_keyword_infos( $keyword ); 548 549 $return = $notfound; 550 if ( isset( $infos[ $field ] ) && $infos[ $field ] !== false ) 551 $return = $infos[ $field ]; 552 553 return yourls_apply_filter( 'get_keyword_info', $return, $keyword, $field, $notfound ); 554 } 555 556 /** 557 * Return title associated with keyword. Optional $notfound = string default message if nothing found 558 * 559 * @param string $keyword Short URL keyword 560 * @param false|string $notfound Optional string to return if keyword not found 561 * @return mixed|string 562 */ 563 function yourls_get_keyword_title( $keyword, $notfound = false ) { 564 return yourls_get_keyword_info( $keyword, 'title', $notfound ); 565 } 566 567 /** 568 * Return long URL associated with keyword. Optional $notfound = string default message if nothing found 569 * 570 * @param string $keyword Short URL keyword 571 * @param false|string $notfound Optional string to return if keyword not found 572 * @return mixed|string 573 */ 574 function yourls_get_keyword_longurl( $keyword, $notfound = false ) { 575 return yourls_get_keyword_info( $keyword, 'url', $notfound ); 576 } 577 578 /** 579 * Return number of clicks on a keyword. Optional $notfound = string default message if nothing found 580 * 581 * @param string $keyword Short URL keyword 582 * @param false|string $notfound Optional string to return if keyword not found 583 * @return mixed|string 584 */ 585 function yourls_get_keyword_clicks( $keyword, $notfound = false ) { 586 return yourls_get_keyword_info( $keyword, 'clicks', $notfound ); 587 } 588 589 /** 590 * Return IP that added a keyword. Optional $notfound = string default message if nothing found 591 * 592 * @param string $keyword Short URL keyword 593 * @param false|string $notfound Optional string to return if keyword not found 594 * @return mixed|string 595 */ 596 function yourls_get_keyword_IP( $keyword, $notfound = false ) { 597 return yourls_get_keyword_info( $keyword, 'ip', $notfound ); 598 } 599 600 /** 601 * Return timestamp associated with a keyword. Optional $notfound = string default message if nothing found 602 * 603 * @param string $keyword Short URL keyword 604 * @param false|string $notfound Optional string to return if keyword not found 605 * @return mixed|string 606 */ 607 function yourls_get_keyword_timestamp( $keyword, $notfound = false ) { 608 return yourls_get_keyword_info( $keyword, 'timestamp', $notfound ); 609 } 610 611 /** 612 * Return array of stats for a given keyword 613 * 614 * This function supersedes function yourls_get_link_stats(), deprecated in 1.7.10, with a better naming. 615 * 616 * @since 1.7.10 617 * @param string $shorturl short URL keyword 618 * @return array stats 619 */ 620 function yourls_get_keyword_stats( $shorturl ) { 621 $table_url = YOURLS_DB_TABLE_URL; 622 $shorturl = yourls_sanitize_keyword( $shorturl ); 623 624 $res = yourls_get_db()->fetchObject("SELECT * FROM `$table_url` WHERE `keyword` = :keyword", array('keyword' => $shorturl)); 625 626 if( !$res ) { 627 // non existent link 628 $return = array( 629 'statusCode' => '404', 630 'message' => 'Error: short URL not found', 631 ); 632 } else { 633 $return = array( 634 'statusCode' => '200', 635 'message' => 'success', 636 'link' => array( 637 'shorturl' => yourls_link($res->keyword), 638 'url' => $res->url, 639 'title' => $res->title, 640 'timestamp'=> $res->timestamp, 641 'ip' => $res->ip, 642 'clicks' => $res->clicks, 643 ) 644 ); 645 } 646 647 return yourls_apply_filter( 'get_link_stats', $return, $shorturl ); 648 } 649 650 /** 651 * Return array of keywords that redirect to the submitted long URL 652 * 653 * @since 1.7 654 * @param string $longurl long url 655 * @param string $order Optional SORT order (can be 'ASC' or 'DESC') 656 * @return array array of keywords 657 */ 658 function yourls_get_longurl_keywords( $longurl, $order = 'ASC' ) { 659 $longurl = yourls_sanitize_url($longurl); 660 $table = YOURLS_DB_TABLE_URL; 661 $sql = "SELECT `keyword` FROM `$table` WHERE `url` = :url"; 662 663 if (in_array($order, array('ASC','DESC'))) { 664 $sql .= " ORDER BY `keyword` ".$order; 665 } 666 667 return yourls_apply_filter( 'get_longurl_keywords', yourls_get_db()->fetchCol($sql, array('url'=>$longurl)), $longurl ); 668 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Wed Nov 26 05:10:06 2025 | Cross-referenced by PHPXref 0.7.1 |