/**
  * Change all links with the specified URL to a new URL.
  *
  * @param string $field_name
  * @param blcParser $parser
  * @param string $new_url
  * @param string $old_url
  * @param string $old_raw_url
  * @return array|WP_Error The new value of raw_url on success, or an error object if something went wrong.
  */
 function edit_link($field_name, $parser, $new_url, $old_url = '', $old_raw_url = '')
 {
     //Ensure we're operating on a consistent copy of the wrapped object.
     /* 
     Explanation 
     
     Consider this scenario where the container object wraps a blog post : 
     	1) The container object gets created and loads the post data. 
     	2) Someone modifies the DB data corresponding to the post.
     	3) The container tries to edit a link present in the post. However, the pots
     	has changed since the time it was first cached, so when the container updates
     	the post with it's changes, it will overwrite whatever modifications were made
     	in step 2.
     	
     This would not be a problem if WP entities like posts and comments were 
     actually real objects, not just bags of key=>value pairs, but oh well.
     	
     Therefore, it is necessary to re-load the wrapped object before editing it.   
     */
     $this->get_wrapped_object(true);
     //Get the current value of the field that needs to be edited.
     $old_value = $this->get_field($field_name);
     //Have the parser modify the specified link. If successful, the parser will
     //return an associative array with two keys - 'content' and 'raw_url'.
     //Otherwise we'll get an instance of WP_Error.
     $edit_result = $parser->edit($old_value, $new_url, $old_url, $old_raw_url);
     if (is_wp_error($edit_result)) {
         return $edit_result;
     }
     //Update the field with the new value returned by the parser.
     $update_result = $this->update_field($field_name, $edit_result['content'], $old_value);
     if (is_wp_error($update_result)) {
         return $update_result;
     }
     //Return the new values to the instance.
     unset($edit_result['content']);
     //(Except content, which it doesn't need.)
     return $edit_result;
 }
 /**
  * Remove all links with the specified URL, leaving their anchor text intact.
  *
  * @param string $field_name
  * @param blcParser $parser
  * @param string $url
  * @param string $raw_url
  * @return bool|WP_Error True on success, or an error object if something went wrong.
  */
 function unlink($field_name, $parser, $url, $raw_url = '')
 {
     //Ensure we're operating on a consistent copy of the wrapped object.
     $this->get_wrapped_object(true);
     $old_value = $this->get_field($field_name);
     $new_value = $parser->unlink($old_value, $url, $raw_url);
     if (is_wp_error($new_value)) {
         return $new_value;
     }
     return $this->update_field($field_name, $new_value, $old_value);
 }
 /**
  * Change a meta field containing the specified URL to a new URL.
  *
  * @param string $field_name Meta name
  * @param blcParser $parser
  * @param string $new_url New URL.
  * @param string $old_url
  * @param string $old_raw_url Old meta value.
  * @return string|WP_Error The new value of raw_url on success, or an error object if something went wrong.
  */
 function edit_link($field_name, $parser, $new_url, $old_url = '', $old_raw_url = '')
 {
     /*
     FB::log(sprintf(
     	'Editing %s[%d]:%s - %s to %s',
     	$this->container_type,
     	$this->container_id,
     	$field_name, 
     	$old_url,
     	$new_url
     ));
     */
     if (empty($old_raw_url)) {
         $old_raw_url = $old_url;
     }
     //Get the current values of the field that needs to be edited.
     //The default metadata parser ignores them, but we're still going
     //to set this argument to a valid value in case someone writes a
     //custom meta parser that needs it.
     $old_value = $this->get_field($field_name);
     //Get the new field value (a string).
     $edit_result = $parser->edit($old_value, $new_url, $old_url, $old_raw_url);
     if (is_wp_error($edit_result)) {
         return $edit_result;
     }
     //Update the field with the new value returned by the parser.
     //Notice how $old_raw_url is usead instead of $old_value. $old_raw_url contains the entire old
     //value of the metadata field (see blcMetadataParser::parse()) and thus can be used to
     //differentiate between multiple meta fields with identical names.
     $update_result = $this->update_field($field_name, $edit_result['content'], $old_raw_url);
     if (is_wp_error($update_result)) {
         return $update_result;
     }
     //Return the new "raw" URL.
     return $edit_result['raw_url'];
 }