Advertisement
Guest User

qTranslate slug with widget + category support (beta)

a guest
Sep 12th, 2011
693
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 36.01 KB | None | 0 0
  1. <?php
  2. /*
  3. Plugin Name: qTranslate slug with Widget
  4. Plugin URI: http://www.3dolab.net/en/261/qtranslateslug-plugin-widget
  5. Plugin Description: Allows to define a slug for each language. Widget for language selection.
  6. Version: 0.4.1
  7. Author: 3DOlab
  8. Author URI: http://www.3dolab.net
  9.  
  10. 0.4.1 - implemented slug translation for categories (more or less added Marco del Precio code you can download here: http://www.qianqin.de/qtranslate/forum/viewtopic.php?p=7401#p7401). TLD Patch http://www.qianqin.de/qtranslate/forum/viewtopic.php?p=7499#p7499 NOT implemented. Works for menu items, not for get_permalink
  11.  
  12. */
  13.  
  14. /*
  15. this plugin is a complete fork of the original qTranslate slug
  16. developed by Cimatti Consulting http://www.cimatti.it
  17.  
  18. This program is free software; you can redistribute it and/or
  19. modify it under the terms of the GNU General Public License
  20. as published by the Free Software Foundation; either version 2
  21. of the License, or (at your option) any later version.
  22.  
  23. This program is distributed in the hope that it will be useful,
  24. but WITHOUT ANY WARRANTY; without even the implied warranty of
  25. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  26. GNU General Public License for more details.
  27.  
  28. You should have received a copy of the GNU General Public License
  29. along with this program; if not, write to the Free Software
  30. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  31.  
  32.  
  33. The full copy of the GNU General Public License is available here: http://www.gnu.org/licenses/gpl.txt
  34.  
  35. */
  36.  
  37. /* Notes
  38.  * fb() is a function defined by the WP-FirePHP plugin <http://wordpress.org/extend/plugins/wp-firephp/>, that allows debug using Firefox, Firebug and FirePHP.
  39.  *
  40.  * TODO:
  41.  * generate translated slug automatically from the translated title
  42.  * check if the slug is already used, and add a progressive number in this case
  43.  * force the use of the translated slug if defined
  44.  * force to show a page/post only at the correct URL
  45.  * try to redirect from a wrong URL to a correct URL
  46.  * keep track of renamed slugs, redirecting from old to new slugs
  47.  * translate categories and tags slugs.
  48.  */
  49.  
  50. // Codes used in the database to indicate posts, pages, categories and tags.
  51. define ('QTS_POST',1);
  52. define ('QTS_PAGE',2);
  53. define ('QTS_CAT',3);
  54. define ('QTS_TAG',4);
  55.  
  56. /**
  57.  * Variable used to override the language
  58.  */
  59. $qts_use_language = null;
  60.  
  61. /**
  62.  * Array of translated versions of the current url
  63.  */
  64. $qts_self_url = array();
  65.  
  66.  
  67. /**
  68.  * Function invoked during the installation of the module. It creates or updates the tables
  69.  */
  70. function qTranslateSlug_install(){
  71.     global $wpdb;
  72.  
  73.     $table_name = $wpdb->prefix.'qtranslate_slug';
  74.     //die(); /* echo don't work !! */
  75.     require_once(ABSPATH.'wp-admin/includes/upgrade.php');
  76.  
  77.     /* is the table existing? */
  78.     if( $wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name){
  79.         $sql = 'CREATE TABLE ' . $table_name . ' (
  80.                     qts_type TINYINT(3) UNSIGNED NOT NULL,
  81.                     qts_id BIGINT(20) UNSIGNED NOT NULL,
  82.                     qts_lang VARCHAR(6) NOT NULL,
  83.                     qts_slug VARCHAR(200) NOT NULL,
  84.                     PRIMARY KEY id_lang (qts_type, qts_id, qts_lang),
  85.                     KEY post_name_lang (qts_slug, qts_type, qts_lang)
  86.         );';
  87.         dbDelta($sql);
  88.     }
  89. }
  90. register_activation_hook( __FILE__  , 'qTranslateSlug_install');
  91.  
  92. /**
  93.  * Function called when query parameters are processed by Wordpress.
  94.  *
  95.  * @param $q query parameters
  96.  * @return array() $q processed
  97.  */
  98. function qTranslateSlug_filter_request($q){
  99.     global $q_config, $wpdb, $qts_use_language, $qts_self_url, $qts_reset_self_url;
  100.  
  101.     if ($qts_use_language !== null){
  102.         $lang = (string) $qts_use_language;
  103.     } else {
  104.         if (! isset ($q_config['language'])){
  105.             return $q;
  106.         }
  107.         $lang = (string) $q_config['language'];
  108.     }
  109.  
  110.     //$fb = function_exists('fb');
  111.  
  112.     //$fb && fb($q,'$q') && fb($lang,'$lang');
  113.  
  114.     $new_q = $q;
  115.  
  116.     if (isset($q['name'])) {
  117.         $type = QTS_POST;
  118.         $slug = $q['name'];
  119.         $param = 'p';
  120.         $get_link = 'get_permalink';
  121.         unset($new_q['name']);
  122.     } else if (isset($q['pagename'])) {
  123.         //$type = QTS_PAGE;
  124.         //$slug = $q['pagename'];
  125.         //$param = 'page_id';
  126.         $id = qTranslateSlug_get_page_by_path($q['pagename'], $lang);
  127.         if ($id) {
  128.             unset($new_q['pagename']);
  129.             $q = $new_q;
  130.             $q['page_id']=$id;
  131.             $get_link = 'get_page_link';
  132.         }
  133.     } else if (isset($q['category_name'])) {
  134.         $type = QTS_CAT;
  135.         $slug = $q['category_name'];
  136.         $param = 'cat';
  137.         $get_link = 'get_category_link';
  138.         unset($new_q['category_name']);
  139.     } else if (isset($q['tag'])) {
  140.         $type = QTS_TAG;
  141.         $slug = $q['tag'];
  142.         $param = 'tag_id';
  143.         $get_link = 'get_tag_link';
  144.         unset($new_q['tag']);
  145.     }
  146.  
  147.     if (isset($type)){
  148.         $slugs = explode('/',$slug);
  149.         $slug = array_pop($slugs);
  150.  
  151.         $query = 'SELECT qts_id
  152.                     FROM '.$wpdb->prefix.'qtranslate_slug
  153.                     WHERE \''.$wpdb->escape($slug).'\' = qts_slug
  154.                         AND '.$type.' = qts_type
  155.                                     AND \''.$wpdb->escape($lang).'\' = qts_lang';
  156.         @ $id = $wpdb->get_var($query);
  157.         if ($id) {
  158.             $q = $new_q;
  159.             $q[$param]=$id;
  160.             //$fb && fb($q,'new $q');
  161.         }
  162.         //$fb && fb($type, '$type')
  163.         //    && fb($slug, '$slug')
  164.         //    && fb($param, '$param')
  165.         //    && fb($query, '$query')
  166.         //    && fb($res,'$res');
  167.     }
  168.  
  169.     if (isset($get_link) && $id && (!$qts_self_url)){
  170.         $old_qts_use_language = $qts_use_language;
  171.         foreach($q_config['enabled_languages'] as $l) {
  172.             $qts_use_language = $l;
  173.             $qts_self_url[$l] = $get_link($id);
  174.         }
  175.         $qts_use_language = $old_qts_use_language;
  176.     }
  177.  
  178.     //$fb && fb($q,'new $q');
  179.     return $q;
  180. }
  181. add_filter('request','qTranslateSlug_filter_request');
  182.  
  183. /**
  184.  * Returns the link to the current page in the desired language
  185.  *
  186.  * @param $lang the code of the desired language
  187.  * @return the link for the current page in that language
  188.  */
  189. function qTranslateSlug_getSelfUrl($lang){
  190.     global $qts_self_url;
  191.     if (! isset($qts_self_url[$lang])){
  192.         $qts_self_url[$lang] = qTranslateSlug_convertURL(clean_url($q_config['url_info']['url']), $lang);
  193.     }
  194.     return $qts_self_url[$lang];
  195. }
  196.  
  197. /**
  198.  * Converts an url in another language.
  199.  *
  200.  * This corresponds to qtrans_convertURL, but for now it doesn't check if the url contains translatable slugs.
  201.  * If you need a translation of the current page, you should use qTranslateSlug_getSelfUrl($lang).
  202.  * If you need the translation for a specific page or post id, you should use get_page_link($id) or get_permalink($id).
  203.  *
  204.  * I extracted qTranslateSlug_urlAddLang() from this function if you just need to add language and home path to a clean relative url.
  205.  *
  206.  * @param $url
  207.  * @param $lang
  208.  * @param $forceadmin
  209.  * @return unknown_type
  210.  */
  211. function qTranslateSlug_convertURL($url='', $lang='', $forceadmin = false) {
  212.     if(defined('WP_ADMIN')&&!$forceadmin) return $url;
  213.     global $q_config;
  214.  
  215.     if($lang=='') $lang = $q_config['language'];
  216.     //if($url=='') $url = qTranslateSlug_getSelfUrl($lang);
  217.     if($url=='') $url = clean_url($q_config['url_info']['url']);
  218.     if(!qtrans_isEnabled($lang)) return "";
  219.  
  220.     // & workaround
  221.     $url = str_replace('&amp;','&',$url);
  222.     $url = str_replace('&#038;','&',$url);
  223.  
  224.     // check if it's an external link
  225.     $urlinfo = qtrans_parseURL($url);
  226.     $home = rtrim(get_option('home'),"/");
  227.     if($urlinfo['host']!='') {
  228.         // check for already existing pre-domain language information
  229.         if($q_config['url_mode'] == QT_URL_DOMAIN && preg_match("#^([a-z]{2}).#i",$urlinfo['host'],$match)) {
  230.             if(qtrans_isEnabled($match[1])) {
  231.                 // found language information, remove it
  232.                 $url = preg_replace("/".$match[1]."\./i","",$url, 1);
  233.                 // reparse url
  234.                 $urlinfo = qtrans_parseURL($url);
  235.             }
  236.         }
  237.         if(substr($url,0,strlen($home))!=$home) {
  238.             return $url;
  239.         }
  240.         // strip home path
  241.         $url = substr($url,strlen($home));
  242.     } else {
  243.         // relative url, strip home path
  244.         $homeinfo = qtrans_parseURL($home);
  245.         if($homeinfo['path']==substr($url,0,strlen($homeinfo['path']))) {
  246.             $url = substr($url,strlen($homeinfo['path']));
  247.         }
  248.     }
  249.  
  250.     // check for query language information and remove if found
  251.     if(preg_match("#(&|\?)lang=([^&\#]+)#i",$url,$match) && qtrans_isEnabled($match[2])) {
  252.         $url = preg_replace("#(&|\?)lang=".$match[2]."&?#i","$1",$url);
  253.     }
  254.  
  255.     // remove any slashes out front
  256.     $url = ltrim($url,"/");
  257.  
  258.     // remove any useless trailing characters
  259.     $url = rtrim($url,"?&");
  260.  
  261.     // reparse url without home path
  262.     $urlinfo = qtrans_parseURL($url);
  263.     // check if its a link to an ignored file type
  264.     $ignore_file_types = preg_split('/\s*,\s*'.'/', strtolower($q_config['ignore_file_types']));
  265.     $pathinfo = pathinfo($urlinfo['path']);
  266.     if(isset($pathinfo['extension']) && in_array(strtolower($pathinfo['extension']), $ignore_file_types)) {
  267.         return $home."/".$url;
  268.     }
  269.  
  270.     return qTranslateSlug_urlAddLang($url, $lang, $urlinfo, $home);
  271. }
  272.  
  273. /**
  274.  * Adds home path and language to an already cleaned URL.
  275.  * It doesn't reparse the url, and supposes $url is a clean relative url.
  276.  * You may pass $urlinfo and $home if you have already them.
  277.  *
  278.  * @param $url the relative url
  279.  * @param $lang the desired language
  280.  * @param $urlinfo result of qtrans_parseURL($url)
  281.  * @param $home result of rtrim(get_option('home'),"/")
  282.  * @return the absolute url with language informations
  283.  */
  284. function qTranslateSlug_urlAddLang ($url, $lang='', $urlinfo='', $home='') {
  285.     global $q_config;
  286.  
  287.     if($lang=='') $lang = $q_config['language'];
  288.     if($urlinfo=='') $urlinfo = qtrans_parseURL($url);
  289.     if($home=='') $home = rtrim(get_option('home'),"/");
  290.  
  291.     switch($q_config['url_mode']) {
  292.         case QT_URL_PATH:   // pre url
  293.             // might already have language information
  294.             if(preg_match("#^([a-z]{2})/#i",$url,$match)) {
  295.                 if(qtrans_isEnabled($match[1])) {
  296.                     // found language information, remove it
  297.                     $url = substr($url, 3);
  298.                 }
  299.             }
  300.             //if(!$q_config['hide_default_language']||$lang!=$q_config['default_language']) $url = $lang."/".$url;
  301.             //Check for older version of qtranslate without hide_default_language option
  302.             if ( ($lang!=$q_config['default_language']) || (isset($q_config['hide_default_language']) && (!$q_config['hide_default_language']))) $url = $lang."/".$url;
  303.             break;
  304.         case QT_URL_DOMAIN: // pre domain
  305.             //if(!$q_config['hide_default_language']||$lang!=$q_config['default_language']) $home = preg_replace("#//#","//".$lang.".",$home,1);
  306.             //Check for older version of qtranslate without hide_default_language option
  307.             if ( ($lang!=$q_config['default_language']) || (isset($q_config['hide_default_language']) && (!$q_config['hide_default_language']))) $home = preg_replace("#//#","//".$lang.".",$home,1);
  308.             break;
  309.         default: // query
  310.             //Check for older version of qtranslate without hide_default_language option
  311.             if ( ($lang!=$q_config['default_language']) || (isset($q_config['hide_default_language']) && (!$q_config['hide_default_language']))) {
  312.                 if(strpos($url,'?')===false) {
  313.                     $url .= '?';
  314.                 } else {
  315.                     $url .= '&';
  316.                 }
  317.                 $url .= "lang=".$lang;
  318.             }
  319.     }
  320.  
  321.     // see if cookies are activated
  322.     if(!$q_config['cookie_enabled'] && !$q_config['url_info']['internal_referer'] && $urlinfo['path'] == '' && $lang == $q_config['default_language'] && $q_config['language'] != $q_config['default_language'] && (isset($q_config['hide_default_language'])?$q_config['hide_default_language']:true)) {
  323.         // :( now we have to make unpretty URLs
  324.         $url = preg_replace("#(&|\?)lang=".$match[2]."&?#i","$1",$url);
  325.         if(strpos($url,'?')===false) {
  326.             $url .= '?';
  327.         } else {
  328.             $url .= '&';
  329.         }
  330.         $url .= "lang=".$lang;
  331.     }
  332.     // &amp; workaround
  333.     $complete = str_replace('&','&amp;',$home."/".$url);
  334.     return $complete;
  335. }
  336.  
  337. //Activates filters defined by this module
  338. add_filter('page_link',                     'qTranslateSlug_page_link', 0, 2);
  339. add_filter('post_link',                     'qTranslateSlug_post_link', 0, 3);
  340. add_filter('category_link',             'qTranslateSlug_category_link', 0, 2);
  341. add_filter('tag_link',                      'qTranslateSlug_tag_link');
  342.  
  343. //add_filter('the_permalink',          'qTranslateSlug_convertURL', 0, 4);
  344.  
  345. /**
  346.  * Disables qtranslate filter for the link managed by this module
  347.  */
  348. function qTranslateSlug_remove_qtrans_filters(){
  349.     remove_filter('page_link', 'qtrans_convertURL');
  350.     remove_filter('post_link', 'qtrans_convertURL');
  351.     remove_filter('category_link', 'qtrans_convertURL');
  352.     remove_filter('tag_link', 'qtrans_convertURL');
  353.  
  354. //  remove_filter('the_permalink',          'qtrans_convertURL');
  355. }
  356. add_action('plugins_loaded','qTranslateSlug_remove_qtrans_filters');
  357.  
  358. //TODO: Links that may have to be checked
  359. //add_filter('category_feed_link',          'qtrans_convertURL');
  360. //add_filter('the_permalink',                   'qtrans_convertURL');
  361. //add_filter('feed_link',                       'qtrans_convertURL');
  362. //add_filter('post_comments_feed_link',     'qtrans_convertURL');
  363. //add_filter('tag_feed_link',                   'qtrans_convertURL');
  364. //add_filter('clean_url',                       'qtrans_convertURL');
  365.  
  366. /**
  367.  * Filter that translates the slug parts in a page link
  368.  *
  369.  * @param $link the link for the page generated by Wordpress
  370.  * @param $id the id of the page
  371.  * @return the link translated
  372.  */
  373. function qTranslateSlug_page_link($link, $id){
  374.     //$fb = function_exists('fb');
  375.     //$fb && fb($link,'start $link') && fb($id, 'start $id');
  376.     global $wpdb,$q_config, $qts_use_language;
  377.     $lang = ($qts_use_language === null)?$q_config['language']:$qts_use_language;
  378.  
  379.     $home = rtrim(get_option('home'),"/");
  380.     $link = substr($link,strlen($home));
  381.     $link = ltrim($link,"/");
  382.     $link = rtrim($link,"?&");
  383.     $urlinfo = qtrans_parseURL($link);
  384.     if ($urlinfo['query']){
  385.         return qTranslateSlug_urlAddLang($link, $lang, $urlinfo, $home);
  386.     }
  387.     $linkParts = explode('/', $link);
  388.     $i = count($linkParts) - 1;
  389.  
  390.     if ($linkParts[$i] === ''){
  391.         $i--;
  392.     }
  393.  
  394.     do {
  395.         $id = (int)$id;
  396.         $query = 'SELECT post_parent, qts_slug
  397.                     FROM '.$wpdb->posts.' p
  398.                         LEFT JOIN ( SELECT *
  399.                             FROM '.$wpdb->prefix.'qtranslate_slug
  400.                             WHERE '.QTS_PAGE.' = qts_type
  401.                                 AND '.$id.' = qts_id
  402.                                 AND \''.$wpdb->escape($lang).'\' = qts_lang
  403.                         ) qts ON p.ID = qts.qts_id
  404.                     WHERE '.$id.' = ID';
  405.         @ $res = $wpdb->get_row($query,ARRAY_A);
  406.         //$fb && fb($query, '$query') && fb($res, '$res');
  407.  
  408.         if (!$res) {
  409.             break;
  410.         }
  411.  
  412.         $parent = $res['post_parent'];
  413.         $slug = $res['qts_slug'];
  414.         if ($slug) {
  415.             $linkParts[$i] = $slug;
  416.         }
  417.  
  418.         if ((!$parent) || ($parent == $id)){
  419.             break;
  420.         }
  421.  
  422.         $id = $parent;
  423.         $i--;
  424.     } while ($i >= 0);
  425.  
  426.     $link = implode('/',$linkParts);
  427.  
  428.     $ret = qTranslateSlug_urlAddLang($link, $lang, $urlinfo, $home);
  429.     //$fb && fb($link, 'end $link') && fb($id, 'end $id') && fb($ret,'return');
  430.  
  431.     return $ret;
  432. }
  433.  
  434. /**
  435.  * Filter that translates the slug in a post link
  436.  *
  437.  * @param $link the link generated by wordpress
  438.  * @param $post the post data
  439.  * @param $leavename parameter used by get_permalink. Whether to keep post name or page name.
  440.  * @return the link translated
  441.  */
  442. function qTranslateSlug_post_link($link, $post, $leavename){
  443.     global $wpdb, $q_config, $qts_use_language;
  444.  
  445.     //$fb = function_exists('fb');
  446.     //$fb && fb($link, 'initial $link') && fb($post, '$post');
  447.  
  448.     $lang = ($qts_use_language === null)?$q_config['language']:$qts_use_language;
  449.  
  450.     $permalink = get_option('permalink_structure');
  451.  
  452.     $home = rtrim(get_option('home'),"/");
  453.  
  454.     $trans_slug = null;
  455.  
  456.     if ((!empty($post->ID)) && ('' != $permalink) && !in_array($post->post_status, array('draft', 'pending')) ) {
  457.         $query = $wpdb->prepare(
  458. "       SELECT qts_slug
  459.             FROM {$wpdb->prefix}qtranslate_slug
  460.             WHERE %d = qts_type
  461.                 AND %d = qts_id
  462.                 AND %s = qts_lang",
  463.             QTS_POST, $post->ID, $lang);
  464.         @$trans_slug = $wpdb->get_var($query);
  465.         //$fb && fb($query,'$query') && fb($trans_slug,'$trans_slug');
  466.     }
  467.     if ($trans_slug !== null) {
  468.         $unixtime = strtotime($post->post_date);
  469.  
  470.             $rewritecode = array(
  471.                 '%year%',
  472.                 '%monthnum%',
  473.                 '%day%',
  474.                 '%hour%',
  475.                 '%minute%',
  476.                 '%second%',
  477.                 $leavename? '' : '%postname%',
  478.                 '%post_id%',
  479.                 '%category%',
  480.                 '%author%',
  481.                 $leavename? '' : '%pagename%',
  482.             );
  483.  
  484.         //TO BE TESTED/REFINED [was:TODO]: translate category slug
  485.             //START Matteo Plebani: matteo@comunicrea.com
  486.         $category = '';
  487.         if ( strpos($permalink, '%category%') !== false ) {
  488.             $cats = get_the_category($post->ID);
  489.  
  490.             if ( $cats ) {
  491.                 //what happens if post assigned to more than one cat?
  492.                 usort($cats, '_usort_terms_by_ID'); // order by ID
  493.  
  494.                 $currCat = $cats[0]->term_id;
  495.                 $category_slugs = array();
  496.                 while($currCat > 0){
  497.                     //look for the slug translation
  498.                     $query = $wpdb->prepare(
  499.                         "SELECT qts_slug
  500.                         FROM {$wpdb->prefix}qtranslate_slug
  501.                         WHERE %d = qts_type
  502.                             AND %d = qts_id
  503.                             AND %s = qts_lang",
  504.                         QTS_CAT, $currCat, $lang);
  505.                     @$trans_cat_slug = $wpdb->get_var($query);
  506.  
  507.                     $catData = get_category( $currCat );
  508.  
  509.                     if ($trans_cat_slug !== null) {
  510.                         array_push($category_slugs, $trans_cat_slug);
  511.                     }else{
  512.                         array_push($category_slugs, $catData->name);
  513.                     }
  514.                     //get current category parent
  515.                     $currCat = $catData->category_parent;
  516.                 }
  517.                 $category_slugs = array_reverse($category_slugs);
  518.                 $category = implode('/', $category_slugs);
  519.             }
  520.             //END Matteo Plebani: matteo@comunicrea.com
  521.  
  522.             // show default category in permalinks, without
  523.             // having to assign it explicitly
  524.             if ( empty($category) ) {
  525.                 $default_category = get_category( get_option( 'default_category' ) );
  526.                 $category = is_wp_error( $default_category ) ? '' : $default_category->slug;
  527.             }
  528.         }
  529.  
  530.         $author = '';
  531.         if ( strpos($permalink, '%author%') !== false ) {
  532.             $authordata = get_userdata($post->post_author);
  533.             $author = $authordata->user_nicename;
  534.         }
  535.  
  536.         $date = explode(" ",date('Y m d H i s', $unixtime));
  537.         $rewritereplace = array(
  538.             $date[0],
  539.             $date[1],
  540.             $date[2],
  541.             $date[3],
  542.             $date[4],
  543.             $date[5],
  544.             $trans_slug,
  545.             $post->ID,
  546.             $category,
  547.             $author,
  548.             $trans_slug,
  549.         );
  550.         $link = user_trailingslashit(str_replace($rewritecode, $rewritereplace, $permalink), 'single');
  551.     } else {
  552.         $link = substr($link, strlen($home));
  553.     }
  554.     $link = ltrim($link, '/');
  555.     $link = qTranslateSlug_urlAddLang($link,$lang,'', $home);
  556.     //$fb && fb($link,'new $link');
  557.     return $link;
  558. }
  559.  
  560.  
  561. function getParentCategoriesSlugTranslation($link, $catid, $lang) {
  562.     global $wpdb;
  563.     $cat_id = (int)$catid;
  564.     $mycategory = &get_category($cat_id);
  565.     $category_parent_id = $mycategory->category_parent;
  566.     $category_parent_id = (int)$category_parent_id;
  567.     if($category_parent_id != 0) {
  568.             $parentCategory = &get_category($category_parent_id);
  569.             $parentCategorySlug = $parentCategory->slug;
  570.             if ($parentCategorySlug != '') {
  571.                     $query = $wpdb->prepare(
  572.                         "SELECT qts_slug
  573.                         FROM {$wpdb->prefix}qtranslate_slug
  574.                         WHERE %d = qts_type
  575.                             AND %d = qts_id
  576.                             AND %s = qts_lang",
  577.                         QTS_CAT, $category_parent_id, $lang);
  578.                     @$trans_slug = $wpdb->get_var($query);
  579.                     if ($trans_slug !== null) {
  580.                          $link = str_replace($parentCategorySlug, $trans_slug, $link);
  581.                     }
  582.  
  583.                     $parentParentCatId = (int)$parentCategory->category_parent;
  584.                     if($parentParentCatId != 0) {
  585.                             return getParentCategoriesSlugTranslation($link, $category_parent_id, $lang);
  586.                     }
  587.                     else {
  588.                             return $link;
  589.                     }
  590.             }
  591.             else {
  592.                     return $link;
  593.             }
  594.     }
  595.     else {
  596.             return $link;
  597.     }
  598. }
  599.  
  600.  
  601. function qTranslateSlug_category_link($link, $id){
  602.     //TODO: implement it!
  603.     global $wpdb, $q_config, $qts_use_language, $wp_query;
  604.     $lang = ($qts_use_language === null)?$q_config['language']:$qts_use_language;
  605.     $home = rtrim(get_option('home'),"/");
  606.  
  607.  
  608.     //Marco  INIZIO
  609.     $trans_slug = null;
  610.     $permalink = get_option('permalink_structure');
  611.  
  612.     $category_id = '';
  613.     $category_slug = '';
  614.  
  615.     $cat_id = (int)$id;
  616.     $mycategory = &get_category($cat_id);
  617.     $category_slug = $mycategory->slug;
  618.     $category_id = $id;
  619.  
  620.     if (($category_id != '') && ('' != $permalink) && ($category_slug != '')) {
  621.         $query = $wpdb->prepare(
  622. "    SELECT qts_slug
  623.             FROM {$wpdb->prefix}qtranslate_slug
  624.             WHERE %d = qts_type
  625.                 AND %d = qts_id
  626.                 AND %s = qts_lang",
  627.             QTS_CAT, $category_id, $lang);
  628.         @$trans_slug = $wpdb->get_var($query);
  629.         //$fb && fb($query,'$query') && fb($trans_slug,'$trans_slug');
  630.     }
  631.     //Marco  FINE
  632.  
  633.     $link = ltrim(substr($link, strlen($home)), '/');
  634.  
  635.     //Marco  INIZIO
  636.     if ($trans_slug !== null) {
  637.         $link = str_replace($category_slug, $trans_slug, $link);
  638.     }
  639.     $link = getParentCategoriesSlugTranslation($link, $cat_id, $lang);
  640.     //Marco  FINE
  641.  
  642.     //Marco   fine
  643.     return qTranslateSlug_urlAddLang($link,$lang,'',$home);
  644. }
  645.  
  646. function qTranslateSlug_tag_link($link){
  647.     //TODO: implement it!
  648.     global $wpdb, $q_config, $qts_use_language;
  649.     $lang = ($qts_use_language === null)?$q_config['language']:$qts_use_language;
  650.     $home = rtrim(get_option('home'),"/");
  651.     $link = ltrim(substr($link, strlen($home)), '/');
  652.     return qTranslateSlug_urlAddLang($link,$lang,'',$home);
  653. }
  654.  
  655. /**
  656.  * Returns the id of the page with the specified path.
  657.  *
  658.  * @param $page_path the path
  659.  * @param $lang optional, the desired language
  660.  * @return id of the page
  661.  */
  662. function qTranslateSlug_get_page_by_path($page_path, $lang = '') {
  663.     global $wpdb, $q_config, $qts_use_language;
  664.     //$fb = function_exists('fb');
  665.     if ($lang == ''){
  666.         $lang = ($qts_use_language === null)?$q_config['language']:$qts_use_language;
  667.     }
  668.     $page_path = rawurlencode(urldecode($page_path));
  669.     $page_path = str_replace('%2F', '/', $page_path);
  670.     $page_path = str_replace('%20', ' ', $page_path);
  671.     $page_paths = '/' . trim($page_path, '/');
  672.     $page_paths = explode('/', $page_paths);
  673.     $spage_paths = array();
  674.     $full_path = '';
  675.     foreach( (array) $page_paths as $pathdir){
  676.             $pathdir = sanitize_title($pathdir);
  677.             if ($pathdir !== ''){
  678.                 $spage_paths[] = $pathdir;
  679.                 $full_path .= '/'.$pathdir;
  680.             }
  681.     }
  682.     $leaf_path = array_pop($spage_paths);
  683.  
  684.     /* This makes invalid the default slug, if it was defined a slug in the desired language.
  685.      * However, without other modifications, the default slug is found anyway by wordpress, so we can find it here.
  686.     $query = $wpdb->prepare(
  687. "       (SELECT ID, qts_slug AS post_name, post_parent
  688.             FROM {$wpdb->posts}, {$wpdb->prefix}qtranslate_slug
  689.             WHERE %s = qts_slug
  690.                 AND %d = qts_type
  691.                 AND %s = qts_lang
  692.                 AND qts_id = ID)
  693.             UNION (SELECT ID, post_name, post_parent
  694.             FROM $wpdb->posts
  695.             WHERE post_name = %s
  696.                 AND (post_type = 'page' OR post_type = 'attachment')
  697.                 AND (SELECT qts_id
  698.                         FROM {$wpdb->prefix}qtranslate_slug
  699.                             WHERE %d = qts_type
  700.                                 AND ID = qts_id
  701.                                 AND %s = qts_lang
  702.                         LIMIT 1) IS NULL)",
  703.         $leaf_path, QTS_PAGE, $lang, $leaf_path, QTS_PAGE, $lang ); */
  704.  
  705.     $query = $wpdb->prepare(
  706. "       (SELECT ID, qts_slug AS post_name, post_parent
  707.             FROM {$wpdb->posts}, {$wpdb->prefix}qtranslate_slug
  708.             WHERE %s = qts_slug
  709.                 AND %d = qts_type
  710.                 AND %s = qts_lang
  711.                 AND qts_id = ID)
  712.             UNION (SELECT ID, post_name, post_parent
  713.             FROM $wpdb->posts
  714.             WHERE post_name = %s AND (post_type = 'page' OR post_type = 'attachment'))",
  715.         $leaf_path, QTS_PAGE, $lang, $leaf_path );
  716.     $pages = $wpdb->get_results($query);
  717.  
  718.     //$fb && fb($query, 'pages query') && fb($pages, '$pages');
  719.  
  720.     foreach ($pages as $page) {
  721.         $path = '/' . $leaf_path;
  722.         $level = count($spage_paths);
  723.         $curpage = $page;
  724.         while ($curpage->post_parent != 0) {
  725.                 $level--;
  726.                 if ($level < 0) continue 2;
  727.             $curpage = $wpdb->get_row( $wpdb->prepare(
  728.                 "SELECT ID, post_name, post_parent, qts_slug
  729.                     FROM $wpdb->posts p
  730.                         LEFT JOIN ( SELECT *
  731.                             FROM {$wpdb->prefix}qtranslate_slug
  732.                             WHERE %d = qts_type
  733.                                 AND %d = qts_id
  734.                                 AND %s = qts_lang
  735.                         ) qts on p.ID = qts.qts_id
  736.                     WHERE ID = %d
  737.                     and post_type='page'",
  738.             QTS_PAGE, $curpage->post_parent, $lang, $curpage->post_parent ));
  739.             /* This makes invalid the default slug, if it was defined a slug in the desired language.
  740.             * However, without other modifications, the default slug is found anyway by wordpress, so we can find it here.
  741.             if ($curpage->qts_slug){
  742.                     if ($curpage->qts_slug === $spage_paths[$level]){
  743.                         $path = '/' . $curpage->qts_slug . $path;
  744.                     } else {
  745.                         continue 2;
  746.                     }
  747.             }*/
  748.             if ($curpage->qts_slug === $spage_paths[$level]){
  749.                 $path = '/' . $curpage->qts_slug . $path;
  750.             } else if ($curpage->post_name === $spage_paths[$level]) {
  751.                 $path = '/' . $curpage->post_name . $path;
  752.             } else {
  753.                 continue 2;
  754.             }
  755.         }
  756.  
  757.         if ( $path === $full_path ) {
  758.                 //$fb && fb($level, 'final $level') && fb ($page->ID, '$page->ID');
  759.             return $page->ID;
  760.         }
  761.     }
  762.  
  763.     return null;
  764. }
  765.  
  766. //Actions used to insert and edit the slug translations
  767. add_action('admin_menu', 'qTranslateSlug_add_custom_box');
  768. add_action('save_post', 'qTranslateSlug_save_postdata', 10, 2);
  769.  
  770. add_action ('edit_category_form_fields', 'qTranslateSlug_category_fields');
  771. add_action ( 'edited_category', 'save_qTranslateSlug_category_fileds');
  772.  
  773. function qTranslateSlug_add_custom_box() {
  774.     if( function_exists( 'add_meta_box' )) {
  775.         add_meta_box( 'qts_sectionid', __( 'qTranslate Slug translation', 'qts_textdomain' ),
  776.                                 'qTranslateSlug_custom_box', 'post', 'advanced' );
  777.         add_meta_box( 'qts_sectionid', __( 'qTranslate Slug translation', 'qts_textdomain' ),
  778.                                 'qTranslateSlug_custom_box', 'page', 'advanced' );
  779.      }
  780. }
  781.  
  782. /**
  783.  * Shows the fields where insert the translated slugs in the post and page edit form.
  784.  */
  785. function qTranslateSlug_custom_box() {
  786.     global $post, $wpdb, $q_config;
  787.  
  788.     if ($post->post_type == 'page'){
  789.         echo $post->post_type;
  790.         $post_type = QTS_PAGE;
  791.     } else if ($post->post_type == 'post') {
  792.         $post_type = QTS_POST;
  793.     } else {
  794.         return;
  795.     }
  796.  
  797.     $query = $wpdb->prepare(
  798.         "SELECT qts_lang, qts_slug
  799.                 FROM {$wpdb->prefix}qtranslate_slug
  800.             WHERE %d = qts_type
  801.                 AND %d = qts_id"
  802.         , $post_type, $post->ID);
  803.     $results = $wpdb->get_results($query);
  804.     $slugs = array();
  805.     foreach ($results as $res) {
  806.         $slugs[$res->qts_lang] = $res->qts_slug;
  807.     }
  808.  
  809.     // Use nonce for verification
  810.     echo '<input type="hidden" name="qts_nonce" id="qts_nonce" value="' .
  811.         wp_create_nonce( 'qts_nonce' ) . '" />';
  812.  
  813.     foreach($q_config['enabled_languages'] as $lang) {
  814.         echo "<label_for='qts_{$lang}_slug'>".__($q_config['language_name'][$lang], 'qtranslate')."</label> ";
  815.         $value = isset($slugs[$lang])?htmlspecialchars($slugs[$lang],ENT_QUOTES):'';
  816.         echo "<input type='text' name='qts_{$lang}_slug' value='$value' /><br />\n";
  817.     }
  818. }
  819.  
  820.  
  821. function qTranslateSlug_category_fields( $tag ) {    //check for existing featured ID
  822.         $t_id = $tag->term_id;
  823.         //$cat_meta = get_option( "category_$t_id");
  824.  
  825.          global $post, $wpdb, $q_config;
  826.         $query = $wpdb->prepare(
  827.         "SELECT qts_lang, qts_slug
  828.                 FROM {$wpdb->prefix}qtranslate_slug
  829.             WHERE %d = qts_type
  830.                 AND %d = qts_id"
  831.         , QTS_CAT, $t_id);
  832.     $results = $wpdb->get_results($query);
  833.     $slugs = array();
  834.     foreach ($results as $res) {
  835.         $slugs[$res->qts_lang] = $res->qts_slug;
  836.     }
  837.  
  838.     echo '<input type="hidden" name="qts_nonce" id="qts_nonce" value="' .
  839.         wp_create_nonce( 'qts_nonce' ) . '" />';
  840.  
  841.     foreach($q_config['enabled_languages'] as $lang) {
  842.         echo "<label_for='qts_{$lang}_slug'>Slug in URL (".__($q_config['language_name'][$lang], 'qtranslate').")</label> ";
  843.         $value = isset($slugs[$lang])?htmlspecialchars($slugs[$lang],ENT_QUOTES):'';
  844.         echo "<input type='text' name='qts_{$lang}_slug' value='$value' /><br />\n";
  845.     }
  846.  
  847. }
  848.  
  849. function save_qTranslateSlug_category_fileds( $term_id ) {
  850.          global $wpdb, $q_config;
  851.  
  852.          if ( !wp_verify_nonce( $_POST['qts_nonce'], 'qts_nonce' )) {
  853.              return;
  854.          }
  855.  
  856.          $type = QTS_CAT;
  857.  
  858.          foreach($q_config['enabled_languages'] as $lang) {
  859.                 if (isset($_POST["qts_{$lang}_slug"])){
  860.                     $slug = sanitize_title($_POST["qts_{$lang}_slug"]);
  861.                     if ($slug === ''){
  862.                         $remove[] = $wpdb->prepare('%s',$lang);
  863.                     } else {
  864.                         $update[] = $wpdb->prepare("(%d,%d,%s,%s)",$type,$term_id,$lang,$slug);
  865.                     }
  866.                 }
  867.          }
  868.  
  869.          if ($remove){
  870.                 $sql = $wpdb->prepare("DELETE FROM {$wpdb->prefix}qtranslate_slug
  871.                             WHERE qts_type = %d
  872.                                 AND qts_id = %d
  873.                                 AND qts_lang in (",
  874.                                     $type, $term_id) . implode(',',$remove) . ')';
  875.                 $res = $wpdb->query($sql);
  876.                 //$fb && fb($sql, 'remove query') && fb($res, 'remove results');
  877.          }
  878.          if ($update){
  879.                 $sql = "INSERT INTO {$wpdb->prefix}qtranslate_slug (qts_type,qts_id,qts_lang,qts_slug) VALUES "
  880.                     . implode(',',$update)
  881.                     . " ON DUPLICATE KEY UPDATE qts_slug=VALUES(qts_slug)";
  882.                 $res = $wpdb->query($sql);
  883.                 //$fb && fb($sql, 'update query') && fb($res, 'update results');
  884.          }
  885. }
  886.  
  887.  
  888. /**
  889.  * Saves the translated slug when the page is saved
  890.  *
  891.  * @param $post_id the post id
  892.  * @param $post the post object
  893.  */
  894. function qTranslateSlug_save_postdata( $post_id, $post ) {
  895.     static $last_done = '';
  896.  
  897.     global $wpdb, $q_config;
  898.     //$fb = function_exists('fb');
  899.     //$fb && fb($_POST,'$_POST') && fb($last_done,'$last_done');
  900.  
  901.     // verify this came from the our screen and with proper authorization,
  902.     // because save_post can be triggered at other times
  903.  
  904.     if ( !wp_verify_nonce( $_POST['qts_nonce'], 'qts_nonce' )) {
  905.         return;
  906.     }
  907.  
  908.     if ( 'page' == $post->post_type ) {
  909.         $type = QTS_PAGE;
  910.         if ( !current_user_can( 'edit_page', $post_id ))
  911.             return;
  912.     } else if ( 'post' == $post->post_type ) {
  913.         $type = QTS_POST;
  914.         if ( !current_user_can( 'edit_post', $post_id ))
  915.             return;
  916.     } else {
  917.         return;
  918.     }
  919.  
  920.     // OK, we're authenticated: we need to find and save the data
  921.     if ($last_done === $post_id) {
  922.         return;
  923.     } else {
  924.         $last_done = $post_id;
  925.     }
  926.  
  927.     $update = array();
  928.     $remove = array();
  929.     /*$title = qtrans_split($_POST["post_title"]);
  930.  
  931.     foreach($title as $key=>$value) {
  932.      if(empty($_POST["qts_".$key."_slug"])) {
  933.             $_POST["qts_".$key."_slug"] = $value;
  934.      }
  935.     }*/
  936.     foreach($q_config['enabled_languages'] as $lang) {
  937.         if (isset($_POST["qts_{$lang}_slug"])){
  938.             $slug = sanitize_title($_POST["qts_{$lang}_slug"]);
  939.             if ($slug === ''){
  940.                 $remove[] = $wpdb->prepare('%s',$lang);
  941.             } else {
  942.                 $update[] = $wpdb->prepare("(%d,%d,%s,%s)",$type,$post_id,$lang,$slug);
  943.             }
  944.         }
  945.     }
  946.  
  947.     if ($remove){
  948.         $sql = $wpdb->prepare("DELETE FROM {$wpdb->prefix}qtranslate_slug
  949.                     WHERE qts_type = %d
  950.                         AND qts_id = %d
  951.                         AND qts_lang in (",
  952.                             $type, $post_id) . implode(',',$remove) . ')';
  953.         $res = $wpdb->query($sql);
  954.         //$fb && fb($sql, 'remove query') && fb($res, 'remove results');
  955.     }
  956.     if ($update){
  957.         $sql = "INSERT INTO {$wpdb->prefix}qtranslate_slug (qts_type,qts_id,qts_lang,qts_slug) VALUES "
  958.             . implode(',',$update)
  959.             . " ON DUPLICATE KEY UPDATE qts_slug=VALUES(qts_slug)";
  960.         $res = $wpdb->query($sql);
  961.         //$fb && fb($sql, 'update query') && fb($res, 'update results');
  962.     }
  963. }
  964.  
  965. // Language Select Code for non-Widget users
  966. function qTranslateSlug_generateLanguageSelectCode($style='', $id='qtrans_language_chooser') {
  967.     global $q_config;
  968.     if($style=='') $style='text';
  969.     if(is_bool($style)&&$style) $style='image';
  970.     switch($style) {
  971.         case 'image':
  972.         case 'text':
  973.         case 'dropdown':
  974.             echo '<ul class="qtrans_language_chooser" id="'.$id.'">';
  975.             foreach(qtrans_getSortedLanguages() as $language) {
  976.                 /*echo '<li';
  977.                 if($language == $q_config['language'])
  978.                     echo ' class="active"';
  979.                 echo '><a href="'.qTranslateSlug_getSelfUrl($language).'"';*/
  980.                 echo '<li class="lang-'.$language;
  981.                 if($language == $q_config['language'])
  982.                     echo ' active';
  983.                 echo '"><a href="'.qTranslateSlug_getSelfUrl($language).'"';
  984.                 // set hreflang
  985.                 echo ' hreflang="'.$language.'"';
  986.                 if($style=='image')
  987.                     echo ' class="qtrans_flag qtrans_flag_'.$language.'"';
  988.                 echo '><span';
  989.                 if($style=='image')
  990.                     echo ' style="display:none"';
  991.                 echo '>'.$q_config['language_name'][$language].'</span></a></li>';
  992.             }
  993.             echo "</ul><div class=\"qtrans_widget_end\"></div>";
  994.             if($style=='dropdown') {
  995.                 echo "<script type=\"text/javascript\">\n// <![CDATA[\r\n";
  996.                 echo "var lc = document.getElementById('".$id."');\n";
  997.                 echo "var s = document.createElement('select');\n";
  998.                 echo "s.id = 'qtrans_select_".$id."';\n";
  999.                 echo "lc.parentNode.insertBefore(s,lc);";
  1000.                 // create dropdown fields for each language
  1001.                 foreach(qtrans_getSortedLanguages() as $language) {
  1002.                     echo qtrans_insertDropDownElement($language, qTranslateSlug_getSelfUrl($language), $id);
  1003.                 }
  1004.                 // hide html language chooser text
  1005.                 echo "s.onchange = function() { document.location.href = this.value;}\n";
  1006.                 echo "lc.style.display='none';\n";
  1007.                 echo "// ]]>\n</script>\n";
  1008.             }
  1009.             break;
  1010.         case 'both':
  1011.             echo '<ul class="qtrans_language_chooser" id="'.$id.'">';
  1012.             foreach(qtrans_getSortedLanguages() as $language) {
  1013.                 echo '<li';
  1014.                 if($language == $q_config['language'])
  1015.                     echo ' class="active"';
  1016.                 echo '><a href="'.qTranslateSlug_getSelfUrl($language).'"';
  1017.                 echo ' class="qtrans_flag_'.$language.' qtrans_flag_and_text"';
  1018.                 echo '><span>'.$q_config['language_name'][$language].'</span></a></li>';
  1019.             }
  1020.             echo "</ul><div class=\"qtrans_widget_end\"></div>";
  1021.             break;
  1022.     }
  1023. }
  1024. class qTranslateslugWidget extends WP_Widget {
  1025.     function qTranslateslugWidget() {
  1026.         $widget_ops = array('classname' => 'widget_qtranslateslug', 'description' => __('Allows your visitors to choose a Language.','qtranslate') );
  1027.         $this->WP_Widget('qtranslateslug', 'qTranslate slug widget', $widget_ops);
  1028.     }
  1029.  
  1030.     function widget($args, $instance) {
  1031.         extract($args);
  1032.  
  1033.         echo $before_widget;
  1034.         $title = empty($instance['title']) ? __('Language', 'qtranslate') : apply_filters('widget_title', $instance['title']);
  1035.         $hide_title = empty($instance['hide-title']) ? false : 'on';
  1036.         $type = $instance['type'];
  1037.         if($type!='text'&&$type!='image'&&$type!='both'&&$type!='dropdown') $type='text';
  1038.  
  1039.         if($hide_title!='on') { echo $before_title . $title . $after_title; };
  1040.         qTranslateSlug_generateLanguageSelectCode($type, $this->id);
  1041.         echo $after_widget;
  1042.     }
  1043.  
  1044.     function update($new_instance, $old_instance) {
  1045.         $instance = $old_instance;
  1046.         $instance['title'] = $new_instance['title'];
  1047.         $instance['hide-title'] = $new_instance['hide-title'];
  1048.         $instance['type'] = $new_instance['type'];
  1049.  
  1050.         return $instance;
  1051.     }
  1052.  
  1053.     function form($instance) {
  1054.         $instance = wp_parse_args( (array) $instance, array( 'title' => '', 'hide-title' => false, 'type' => 'text' ) );
  1055.         $title = $instance['title'];
  1056.         $hide_title = $instance['hide-title'];
  1057.         $type = $instance['type'];
  1058. ?>
  1059.         <p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:', 'qtranslate'); ?> <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo attribute_escape($title); ?>" /></label></p>
  1060.         <p><label for="<?php echo $this->get_field_id('hide-title'); ?>"><?php _e('Hide Title:', 'qtranslate'); ?> <input type="checkbox" id="<?php echo $this->get_field_id('hide-title'); ?>" name="<?php echo $this->get_field_name('hide-title'); ?>" <?php echo ($hide_title=='on')?'checked="checked"':''; ?>/></label></p>
  1061.         <p><?php _e('Display:', 'qtranslate'); ?></p>
  1062.         <p><label for="<?php echo $this->get_field_id('type'); ?>1"><input type="radio" name="<?php echo $this->get_field_name('type'); ?>" id="<?php echo $this->get_field_id('type'); ?>1" value="text"<?php echo ($type=='text')?' checked="checked"':'' ?>/> <?php _e('Text only', 'qtranslate'); ?></label></p>
  1063.         <p><label for="<?php echo $this->get_field_id('type'); ?>2"><input type="radio" name="<?php echo $this->get_field_name('type'); ?>" id="<?php echo $this->get_field_id('type'); ?>2" value="image"<?php echo ($type=='image')?' checked="checked"':'' ?>/> <?php _e('Image only', 'qtranslate'); ?></label></p>
  1064.         <p><label for="<?php echo $this->get_field_id('type'); ?>3"><input type="radio" name="<?php echo $this->get_field_name('type'); ?>" id="<?php echo $this->get_field_id('type'); ?>3" value="both"<?php echo ($type=='both')?' checked="checked"':'' ?>/> <?php _e('Text and Image', 'qtranslate'); ?></label></p>
  1065.         <p><label for="<?php echo $this->get_field_id('type'); ?>4"><input type="radio" name="<?php echo $this->get_field_name('type'); ?>" id="<?php echo $this->get_field_id('type'); ?>4" value="dropdown"<?php echo ($type=='dropdown')?' checked="checked"':'' ?>/> <?php _e('Dropdown Box', 'qtranslate'); ?></label></p>
  1066. <?php
  1067.     }
  1068. }
  1069. function qtranslug_widget_init() {
  1070.     register_widget('qTranslateslugWidget');
  1071. }
  1072. add_action('widgets_init', 'qtranslug_widget_init');
  1073. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement