Check links inside buttons and other items of visual composer
-
Hello
I have installed visual composer and the ultimate addons. In this elements broken link checker can’t find broken links.
How can I solve this?
Thank you everyone
-
That’s probably because Visual Composer stores its content in a place where the plugin doesn’t know to look.
By default, Broken Link Checker can only find links in post body, comment text, the blogroll, and a few other places. If Visual Composer stores links in a custom field, you’ll need to enable the “Custom fields” option under “Settings -> Link Checker -> Look For Links In” and add the field name to the list.
On the other hand, if VC uses a custom database table, you’re unfortunately out of luck. This plugin doesn’t have the ability to scan arbitrary tables for links.
(Sorry about the late response, I somehow missed your thread.)
I stumbled upon your post because I was having the same question. Since I couldn’t find a way to check my visual composer links, I wrote a simple plugin myself. To be put in modules/parsers/vc_link.php. Thanks to visual composer for being so modular.
<?php /* Plugin Name: Visual Composer links Description: Example : <code>[dt-button url="https://example.com/" text="link text"]</code>, plugin based on htmllink plugin by Janis Elsts Version: 1.0 Author: Kaj ten Voorde ModuleID: vc ModuleCategory: parser ModuleClassName: blcVCLink ModuleContext: on-demand ModuleLazyInit: true */ class blcVCLink extends blcParser { var $supported_formats = array('html'); /** * Parse a string for VC links - [... url="URL" ..] * * @param string $content The text to parse. * @param string $base_url The base URL to use for normalizing relative URLs. If ommitted, the blog's root URL will be used. * @param string $default_link_text * @return array An array of new blcLinkInstance objects. The objects will include info about the links found, but not about the corresponding container entity. */ function parse($content, $base_url = '', $default_link_text = ''){ //remove all <code></code> blocks first //Find links $params = array( 'base_url' => $base_url, 'default_link_text' => $default_link_text, ); $instances = $this->map($content, array($this, 'parser_callback'), $params); //The parser callback returns NULL when it finds an invalid link. Filter out those nulls //from the list of instances. $instances = array_filter($instances); return $instances; } /** * blcVCLink::parser_callback() * * @access private * * @param array $link * @param array $params * @return blcLinkInstance|null */ function parser_callback($link, $params){ global $blclog; $base_url = $params['base_url']; $url = $raw_url = $link['url']; $url = trim($url); //$blclog->debug(__CLASS__ .':' . __FUNCTION__ . ' Found a link, raw URL = "' . $raw_url . '"'); //Sometimes links may contain shortcodes. Execute them. $url = do_shortcode($url); //Skip empty URLs if ( empty($url) ){ $blclog->warn(__CLASS__ .':' . __FUNCTION__ . ' Skipping the link (empty URL)'); return null; }; //Attempt to parse the URL $parts = @parse_url($url); if(!$parts) { $blclog->warn(__CLASS__ .':' . __FUNCTION__ . ' Skipping the link (parse_url failed)', $url); return null; //Skip invalid URLs }; if ( !isset($parts['scheme']) ){ //No scheme - likely a relative URL. Turn it into an absolute one. //TODO: Also log the original URL and base URL. $url = $this->relative2absolute($url, $base_url); //$base_url comes from $params $blclog->info(__CLASS__ .':' . __FUNCTION__ . ' Convert relative URL to absolute. Absolute URL = "' . $url . '"'); } //Skip invalid links (again) if ( !$url || (strlen($url)<6) ) { $blclog->info(__CLASS__ .':' . __FUNCTION__ . ' Skipping the link (invalid/short URL)', $url); return null; } //Remove left-to-right marks. See: https://en.wikipedia.org/wiki/Left-to-right_mark $ltrm = json_decode('"\u200E"'); $url = str_replace($ltrm, '', $url); $text = $link['text']; //The URL is okay, create and populate a new link instance. $instance = new blcLinkInstance(); $instance->set_parser($this); $instance->raw_url = $raw_url; $instance->link_text = $text; $link_obj = new blcLink($url); //Creates or loads the link $instance->set_link($link_obj); return $instance; } /** * Change all links that have a certain URL to a new URL. * * @param string $content Look for links in this string. * @param string $new_url Change the links to this URL. * @param string $old_url The URL to look for. * @param string $old_raw_url The raw, not-normalized URL of the links to look for. Optional. * @param string $new_text New link text. Optional. * * @return array|WP_Error If successful, the return value will be an associative array with two * keys : 'content' - the modified content, and 'raw_url' - the new raw, non-normalized URL used * for the modified links. In most cases, the returned raw_url will be equal to the new_url. */ function edit($content, $new_url, $old_url, $old_raw_url, $new_text = null){ if ( empty($old_raw_url) ){ $old_raw_url = $old_url; } //Save the old & new URLs for use in the edit callback. $args = array( 'old_url' => $old_raw_url, 'new_url' => $new_url, 'new_text' => $new_text, ); //Find all links and replace those that match $old_url. $content = $this->multi_edit($content, array(&$this, 'edit_callback'), $args); $result = array( 'content' => $content, 'raw_url' => $new_url, ); if ( isset($new_text) ) { $result['text'] = $new_text; } return $result; } function edit_callback($link, $params){ if ($link['url'] == $params['old_url']){ $modified = array( 'url' => $params['new_url'], ); if ( isset($params['text']) ) { $modified['text'] = $params['new_text']; } return $modified; } else { return $link['#raw']; } } public function is_link_text_editable() { return true; } public function is_url_editable() { return true; } /** * Remove all links that have a certain URL, leaving anchor text intact. * * @param string $content Look for links in this string. * @param string $url The URL to look for. * @param string $raw_url The raw, non-normalized version of the URL to look for. Optional. * @return string Input string with all matching links removed. */ function unlink($content, $url, $raw_url){ if ( empty($raw_url) ){ $raw_url = $url; } $args = array( 'old_url' => $raw_url, ); //Find all links and remove those that match $raw_url. $content = $this->multi_edit($content, array(&$this, 'unlink_callback'), $args); return $content; } /** * blcVCLink::unlink_callback() * * @access private * * @param array $link * @param array $params * @return string */ function unlink_callback($link, $params){ //Skip links that don't match the specified URL if ($link['url'] != $params['old_url']){ return $link['#raw']; } $config = blc_get_configuration(); if ( $config->options['mark_removed_links'] ){ //Leave only the anchor text + the removed_link CSS class return sprintf( '<span class="removed_link" title="%s">%s</span>', esc_attr($link['url']), $link['text'] ); } else { //Just the anchor text return $link['text']; } } /** * Get the link text for printing in the "Broken Links" table. * Sub-classes should override this method and display the link text in a way appropriate for the link type. * * @param blcLinkInstance $instance * @param string $context * @return string HTML */ function ui_get_link_text($instance, $context = 'display'){ return strip_tags($instance->link_text); } /** * Apply a callback function to all VC links found in a string and return the results. * * The link data array will contain at least these keys : * 'url' - the URL of the link (with htmlentitydecode() already applied). * '#tag' - the Visual Composer tag * '#raw' - the raw link code, e.g. the entire '<a href="...">...</a>' tag of a VC link. * '#offset' - the offset within $content at which the first character of the link tag was found. * '#link_text' - the link's anchor text, if any. May contain HTML tags. * * Any attributes of the link tag will also be included in the returned array as attr_name => attr_value * pairs. This function will also automatically decode any HTML entities found in attribute values. * * @see blcParser::map() * * @param string $content A text string to parse for links. * @param callback $callback Callback function to apply to all found links. * @param mixed $extra If the optional $extra param. is supplied, it will be passed as the second parameter to the function $callback. * @return array An array of all detected links after applying $callback to each of them. */ function map($content, $callback, $extra = null){ global $blclog; $results = array(); //Find all links //$links = blcUtility::extract_tags($content, 'a', false, true); preg_match_all("/\[[^\]]*url=[^\]]*\]/",$content,$matches,PREG_OFFSET_CAPTURE); foreach($matches[0] as $match) { preg_match_all('/([^= ]*)="([^"]*)"/', $match[0], $match_atts,PREG_OFFSET_CAPTURE); foreach($match_atts[1] as $pos => $match_att) { $param[$match_att[0]] = $match_atts[2][$pos][0]; } $raw = $match[0]; $param = array_merge( $param, array( '#raw' => $raw, '#tag' => substr($raw, 1, strpos($raw, ' ')-1), '#offset' => $match[1], 'url' => isset($param['url'])?$param['url']:'', '#link_text' => $param['text'], ) ); //Prepare arguments for the callback $params = array($param); if ( isset($extra) ){ $params[] = $extra; } //Execute & store :) $results[] = call_user_func_array($callback, $params); } return $results; } /** * Modify all VC links found in a string using a callback function. * * The callback function should return either an associative array or a string. If * a string is returned, the parser will replace the current link with the contents * of that string. If an array is returned, the current link will be modified/rebuilt * by substituting the new values for the old ones. * * htmlentities() will be automatically applied to attribute values (but not to #link_text). * * @see blcParser::multi_edit() * * @param string $content A text string containing the links to edit. * @param callback $callback Callback function used to modify the links. * @param mixed $extra If supplied, $extra will be passed as the second parameter to the function $callback. * @return string The modified input string. */ function multi_edit($content, $callback, $extra = null){ //Just reuse map() + a little helper func. to apply the callback to all links and get modified links $modified_links = $this->map($content, array(&$this, 'execute_edit_callback'), array($callback, $extra)); //Replace each old link with the modified one $offset = 0; foreach($modified_links as $link){ if ( isset($link['#new_raw']) ){ $new_html = $link['#new_raw']; } else { //Assemble the new link tag $new_html = '['.$link['#tag']; foreach ( $link as $name => $value ){ //Skip special keys like '#raw' and '#offset' if ( substr($name, 0, 1) == '#' ){ continue; } $new_html .= sprintf(' %s="%s"', $name, esc_attr( $value )); } $new_html .= ']'; } $content = substr_replace($content, $new_html, $link['#offset'] + $offset, strlen($link['#raw'])); //Update the replacement offset $offset += ( strlen($new_html) - strlen($link['#raw']) ); } return $content; } /** * Helper function for blcHtmlLink::multi_edit() * Applies the specified callback function to each link and merges * the result with the current link attributes. If the callback returns * a replacement HTML tag instead, it will be stored in the '#new_raw' * key of the return array. * * @access protected * * @param array $link * @param array $info The callback function and the extra argument to pass to that function (if any). * @return array */ function execute_edit_callback($link, $info){ list($callback, $extra) = $info; //Prepare arguments for the callback $params = array($link); if ( isset($extra) ){ $params[] = $extra; } $new_link = call_user_func_array($callback, $params); if ( is_array($new_link) ){ $link = array_merge($link, $new_link); } elseif (is_string($new_link)) { $link['#new_raw'] = $new_link; } return $link; } } ?>
- The topic ‘Check links inside buttons and other items of visual composer’ is closed to new replies.