/** * Store the link instance in the database. * Saving the instance will also implicitly save the link record associated with it, if it wasn't already saved. * * @return bool TRUE on success, FALSE on error */ function save() { global $wpdb; /** @var wpdb $wpdb */ //Refresh the locally cached link & container properties, in case //the objects have changed since they were set. if (!is_null($this->_link)) { //If we have a link object assigned, but it's new, it won't have a DB ID yet. //We need to save the link to get the ID and be able to maintain the link <-> instance //association. if ($this->_link->is_new) { $rez = $this->_link->save(); if (!$rez) { return false; } } $this->link_id = $this->_link->link_id; } if (!is_null($this->_container)) { $this->container_type = $this->_container->container_type; $this->container_id = $this->_container->container_id; } //If the link is new, insert a new row into the DB. Otherwise update the existing row. if ($this->is_new) { $q = "\r\n\t\t\tINSERT INTO {$wpdb->prefix}blc_instances\r\n\t\t\t\t ( link_id, container_type, container_id, container_field, parser_type, link_text, link_context, raw_url )\r\n\t\t\tVALUES( %d, %s, %d, %s, %s, %s, %s, %s )"; $q = $wpdb->prepare($q, $this->link_id, $this->container_type, $this->container_id, $this->container_field, $this->parser_type, $this->link_text, $this->link_context, $this->raw_url); $rez = $wpdb->query($q) !== false; if ($rez) { $this->instance_id = $wpdb->insert_id; //If the instance was successfully saved then it's no longer "new". $this->is_new = !$rez; } return $rez; } else { $q = "UPDATE {$wpdb->prefix}blc_instances\r\n\t\t\t \r\n\t\t\t\t SET \r\n\t\t\t\t link_id = %d, \r\n\t\t\t\t\t container_type = %s, \r\n\t\t\t\t\t container_id = %d, \r\n\t\t\t\t\t container_field = %s, \r\n\t\t\t\t\t parser_type = %s, \r\n\t\t\t\t\t link_text = %s, \r\n\t\t\t\t\t link_context = %s, \r\n\t\t\t\t\t raw_url = %s\r\n\t\t\t\t\t \r\n\t\t\t\t WHERE instance_id = %d"; $q = $wpdb->prepare($q, $this->link_id, $this->container_type, $this->container_id, $this->container_field, $this->parser_type, $this->link_text, $this->link_context, $this->raw_url, $this->instance_id); $rez = $wpdb->query($q) !== false; if ($rez) { //FB::info($this, "Instance updated"); } else { //FB::error("DB error while updating instance {$this->instance_id} : {$wpdb->last_error}"); } return $rez; } }
private function blc_set_dismiss_status($dismiss, $params) { if ($this->_checkBLC()) { $link = new blcLink(intval($params['linkID'])); if (!$link->valid()) { return "Oops, I can't find the link " . intval($params['linkID']); } $link->dismissed = $dismiss; if ($link->save()) { $rez = array('old_link_id' => $params['linkID'], 'linkType' => $params['linkType'], 'dismissvalue_set' => 1); } else { $rez = array('error' => 'Action couldn\'t be completed', 'error_code' => 'blc_plugin_action_couldnt_completed_blc_set_dismiss_status'); } return $rez; } else { return array('error' => "Broken Link Checker plugin is not activated", 'error_code' => 'blc_plugin_not_activated_blc_set_dismiss_status'); } }
/** * AJAX hook for the "Unlink" action links in Tools -> Broken Links. * Removes the specified link from all posts and other supported items. * * @return void */ function ajax_unlink() { if (!current_user_can('edit_others_posts') || !check_ajax_referer('blc_unlink', false, false)) { die(json_encode(array('error' => __("You're not allowed to do that!", 'broken-link-checker')))); } if (isset($_POST['link_id'])) { //Load the link $link = new blcLink(intval($_POST['link_id'])); if (!$link->valid()) { die(json_encode(array('error' => sprintf(__("Oops, I can't find the link %d", 'broken-link-checker'), intval($_POST['link_id']))))); } //Try and unlink it $rez = $link->unlink(); if ($rez === false) { die(json_encode(array('error' => __("An unexpected error occured!", 'broken-link-checker')))); } else { $response = array('cnt_okay' => $rez['cnt_okay'], 'cnt_error' => $rez['cnt_error'], 'errors' => array()); foreach ($rez['errors'] as $error) { /** @var WP_Error $error */ array_push($response['errors'], implode(', ', $error->get_error_messages())); } die(json_encode($response)); } } else { die(json_encode(array('error' => __("Error : link_id not specified", 'broken-link-checker')))); } }
/** * blcLink::edit() * Edit all instances of the link by changing the URL. * * Here's how this really works : create a new link with the new URL. Then edit() * all instances and point them to the new link record. If some instance can't be * edited they will still point to the old record. The old record is deleted * if all instances were edited successfully. * * @param string $new_url * @param string $new_text Optional. * @return array An associative array with these keys : * new_link_id - the database ID of the new link. * new_link - the new link (an instance of blcLink). * cnt_okay - the number of successfully edited link instances. * cnt_error - the number of instances that caused problems. * errors - an array of WP_Error objects corresponding to the failed edits. */ function edit($new_url, $new_text = null) { if (!$this->valid()) { return new WP_Error('link_invalid', __("Link is not valid", 'broken-link-checker')); } //FB::info('Changing link '.$this->link_id .' to URL "'.$new_url.'"'); $instances = $this->get_instances(); //Fail if there are no instances if (empty($instances)) { return array('new_link_id' => $this->link_id, 'new_link' => $this, 'cnt_okay' => 0, 'cnt_error' => 0, 'errors' => array(new WP_Error('no_instances_found', __('This link can not be edited because it is not used anywhere on this site.', 'broken-link-checker')))); } //Load or create a link with the URL = $new_url $new_link = new blcLink($new_url); $was_new = $new_link->is_new; if ($new_link->is_new) { //FB::log($new_link, 'Saving a new link'); $new_link->save(); //so that we get a valid link_id } //FB::log("Changing link to $new_url"); if (empty($new_link->link_id)) { //FB::error("Failed to create a new link record"); return array('new_link_id' => $this->link_id, 'new_link' => $this, 'cnt_okay' => 0, 'cnt_error' => 0, 'errors' => array(new WP_Error('link_creation_failed', __('Failed to create a DB entry for the new URL.', 'broken-link-checker')))); } $cnt_okay = $cnt_error = 0; $errors = array(); //Edit each instance. //FB::info('Editing ' . count($instances) . ' instances'); foreach ($instances as $instance) { $rez = $instance->edit($new_url, $this->url, $new_text); if (is_wp_error($rez)) { $cnt_error++; array_push($errors, $rez); //FB::error($instance, 'Failed to edit instance ' . $instance->instance_id); } else { $cnt_okay++; $instance->link_id = $new_link->link_id; $instance->save(); //FB::info($instance, 'Successfully edited instance ' . $instance->instance_id); } } //If all instances were edited successfully we can delete the old link record. //UNLESS this link is equal to the new link (which should never happen, but whatever). if ($cnt_error == 0 && $cnt_okay > 0 && $this->link_id != $new_link->link_id) { $this->forget(false); } //On the other hand, if no instances could be edited and the $new_link was really new, //then delete it. if ($cnt_okay == 0 && $was_new) { $new_link->forget(false); $new_link = $this; } return array('new_link_id' => $new_link->link_id, 'new_link' => $new_link, 'cnt_okay' => $cnt_okay, 'cnt_error' => $cnt_error, 'errors' => $errors); }
/** * AJAX hook for the "Recheck" action. */ public function ajax_recheck() { if (!current_user_can('edit_others_posts') || !check_ajax_referer('blc_recheck', false, false)) { die(json_encode(array('error' => __("You're not allowed to do that!", 'broken-link-checker')))); } if (!isset($_POST['link_id']) || !is_numeric($_POST['link_id'])) { die(json_encode(array('error' => __("Error : link_id not specified", 'broken-link-checker')))); } $id = intval($_POST['link_id']); $link = new blcLink($id); if (!$link->valid()) { die(json_encode(array('error' => sprintf(__("Oops, I can't find the link %d", 'broken-link-checker'), $id)))); } //In case the immediate check fails, this will ensure the link is checked during the next work() run. $link->last_check_attempt = 0; $link->isOptionLinkChanged = true; $link->save(); //Check the link and save the results. $link->check(true); $status = $link->analyse_status(); $response = array('status_text' => $status['text'], 'status_code' => $status['code'], 'http_code' => empty($link->http_code) ? '' : $link->http_code, 'redirect_count' => $link->redirect_count, 'final_url' => $link->final_url); die(json_encode($response)); }
function check($url) { $url = $this->clean_url($url); //Note : Snoopy doesn't work too well with HTTPS URLs. $result = array('broken' => false, 'timeout' => false); $log = ''; //Get the timeout setting from the BLC configuration. $conf = blc_get_configuration(); $timeout = $conf->options['timeout']; $start_time = microtime_float(); //Fetch the URL with Snoopy $snoopy = new Snoopy(); $snoopy->read_timeout = $timeout; //read timeout in seconds $snoopy->agent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)"; //masquerade as IE 7 $snoopy->referer = home_url(); //valid referer helps circumvent some hotlink protection schemes $snoopy->maxlength = 1024 * 5; //load up to 5 kilobytes $snoopy->fetch($this->urlencodefix($url)); $result['request_duration'] = microtime_float() - $start_time; $result['http_code'] = $snoopy->status; //HTTP status code //Snoopy returns -100 on timeout if ($result['http_code'] == -100) { $result['http_code'] = 0; $result['timeout'] = true; } //Build the log $log .= '=== '; if ($result['http_code']) { $log .= sprintf(__('HTTP code : %d', 'broken-link-checker'), $result['http_code']); } else { $log .= __('(No response)', 'broken-link-checker'); } $log .= " ===\n\n"; if ($snoopy->error) { $log .= $snoopy->error . "\n"; } if ($snoopy->timed_out) { $log .= __("Request timed out.", 'broken-link-checker') . "\n"; $result['timeout'] = true; } if (is_array($snoopy->headers)) { $log .= implode("", $snoopy->headers) . "\n"; } //those headers already contain newlines //Redirected? if ($snoopy->lastredirectaddr) { $result['final_url'] = $snoopy->lastredirectaddr; $result['redirect_count'] = $snoopy->_redirectdepth; } else { $result['final_url'] = $url; } //Determine if the link counts as "broken" $result['broken'] = $this->is_error_code($result['http_code']) || $result['timeout']; $log .= "<em>(" . __('Using Snoopy', 'broken-link-checker') . ")</em>"; $result['log'] = $log; //The hash should contain info about all pieces of data that pertain to determining if the //link is working. $result['result_hash'] = implode('|', array($result['http_code'], $result['broken'] ? 'broken' : '0', $result['timeout'] ? 'timeout' : '0', blcLink::remove_query_string($result['final_url']))); return $result; }
/** * @param blcLink $link * @param blcLinkInstance[] $instances */ function column_status($link, $instances) { printf('<table class="mini-status" title="%s">', esc_attr(__('Show more info about this link', 'broken-link-checker'))); $status = $link->analyse_status(); printf('<tr class="link-status-row link-status-%s"> <td> <span class="http-code">%s</span> <span class="status-text">%s</span> </td> </tr>', $status['code'], empty($link->http_code) ? '' : $link->http_code, $status['text']); //Last checked... if ($link->last_check != 0) { $last_check = _x('Checked', 'checked how long ago', 'broken-link-checker') . ' '; $last_check .= blcUtility::fuzzy_delta(time() - $link->last_check, 'ago'); printf('<tr class="link-last-checked"><td>%s</td></tr>', $last_check); } //Broken for... if ($link->broken) { $delta = time() - $link->first_failure; $broken_for = blcUtility::fuzzy_delta($delta); printf('<tr class="link-broken-for"><td>%s %s</td></tr>', __('Broken for', 'broken-link-checker'), $broken_for); } echo '</table>'; }
private function discard() { $information = array(); if (!current_user_can('edit_others_posts')) { $information['error'] = 'NOTALLOW'; return $information; } if (isset($_POST['link_id'])) { //Load the link $link = new blcLink(intval($_POST['link_id'])); if (!$link->valid()) { $information['error'] = 'NOTFOUNDLINK'; // Oops, I can't find the link return $information; } //Make it appear "not broken" $link->broken = false; $link->false_positive = true; $link->last_check_attempt = time(); $link->log = __("This link was manually marked as working by the user."); //Save the changes if ($link->save()) { $information['status'] = 'OK'; $information['last_check_attempt'] = $link->last_check_attempt; } else { $information['error'] = 'COULDNOTMODIFY'; // Oops, couldn't modify the link } } else { $information['error'] = __("Error : link_id not specified"); } return $information; }