Overview

Classes

  • CMLLanguage
  • CMLPost
  • CMLTranslations
  • CMLUtils

Functions

  • cml_dropdown_langs
  • cml_get_browser_lang
  • cml_get_menu
  • cml_get_notice
  • cml_get_the_link
  • cml_is_homepage
  • cml_show_flags
  • Overview
  • Function
  • Tree
  1: <?php
  2: 
  3: /**
  4:  * Check if current url ( or $url ) is the homepage
  5:  *
  6:  * If is set a static page as homepage, the plugin check if
  7:  * current page is front page or its translation
  8:  *
  9:  * @param string $url - ( optional ) url to check
 10:  * 
 11:  */
 12: function cml_is_homepage( $url = null ) {
 13:   global $wpdb;
 14: 
 15:   if( ! empty( $wpdb ) && method_exists( $wpdb, 'is_category' ) ) {
 16:     if( is_category() || is_archive() ) return false;
 17:   }
 18: 
 19:   //Controllo se è stata impostata una pagina "statica" se l'id di questa è = a quello della statica
 20:   if( cml_use_static_page() ) {
 21:     global $wp_query;
 22:     $static_id = get_option( "page_for_posts" ) + get_option( "page_on_front" );
 23: 
 24:     $lang_id = CMLLanguage::get_current_id();
 25:     
 26:     /*
 27:      * on some site get_queried_object_id isn't available on start
 28:      * and I get:
 29:      * Fatal error: Call to a member function get_queried_object_id() on a non-object
 30:      *
 31:      * So ensure that method exists, otherwise I use get_the_ID() method
 32:      */
 33:     /*
 34:      * If I call get_queried_object_id in the footer can happens that
 35:      * queried_object_id is different from "real" queried_object,
 36:      * so I store that info in $GLOBALS to avoid this problem :)
 37:      */
 38:     if( ! isset( $GLOBALS[ '_cml_get_queried_object_id' ] ) ) {
 39:       if( ! empty( $wpdb ) && method_exists( $wpdb, 'get_queried_object' ) ) {
 40:         $GLOBALS[ '_cml_get_queried_object_id' ] = get_queried_object()->ID;
 41:         $GLOBALS[ '_cml_get_queried_object' ] = get_queried_object();
 42: 
 43:         $the_id = & $GLOBALS[ '_cml_get_queried_object_id' ];
 44:       } else {
 45:         if( is_object( get_post() ) ) {
 46:           $the_id = get_the_ID();
 47:           
 48:           $GLOBALS[ '_cml_get_queried_object_id' ] = $the_id;
 49:         }
 50:       }
 51:       
 52:     } else {
 53:       $the_id = $GLOBALS[ '_cml_get_queried_object_id' ];
 54:     }
 55: 
 56:     if( ! empty( $the_id ) ) {
 57:       if( $the_id == $static_id ) return true;  //Yes, it is :)
 58: 
 59:       //Is a translation of front page?
 60:       $linked = CMLPost::get_translation( CMLLanguage::get_current_id(), $the_id  );
 61:       if( !empty($linked) ) {
 62:         return $linked == $static_id;
 63:       }
 64:     }
 65:   }
 66: 
 67:   //I can't use is_home(), because it return empty value, so I have to check
 68:   //it manually
 69:   if( ! empty( $wpdb ) && method_exists( $wpdb, 'is_home' ) ) {
 70:     return is_home();
 71:   }
 72: 
 73:   //Remove language information by url
 74:   CMLUtils::clear_url();
 75: 
 76:   return trailingslashit( CMLUtils::get_clean_url() ) == trailingslashit( CMLUtils::home_url() );
 77: }
 78: 
 79: /**
 80:  * @ignore
 81:  * @internal
 82:  *
 83:  * get page by path
 84:  *
 85:  * On some site I can't use url_to_postid() because
 86:  * $wp_reqruite is empty...
 87:  * 
 88:  */
 89: function cml_get_page_id_by_path($url, $types = null) {
 90:   $url = untrailingslashit( $url );
 91:   $plinks = explode( "/", $url );
 92: 
 93:   if( $types == null ) {
 94:     $types = array_keys( get_post_types() );
 95:   }
 96: 
 97:   $p = cml_get_page_by_path( $url, OBJECT, $types );
 98:   $the_id = is_object( $p ) ? $p->ID : 0;
 99: 
100:   return $the_id;
101: }
102: 
103: /**
104:  * @ignore
105:  * @internal
106:  *
107:  * This is modified version of wordpress function get_page_by_path,
108:  * because original one doesn't works correctly for me
109:  *
110:  * @since 2.1.0
111:  * @uses $wpdb
112:  *
113:  * @param string $page_path Page path
114:  * @param string $output Optional. Output type. OBJECT, ARRAY_N, or ARRAY_A. Default OBJECT.
115:  * @param array $post_type Optional. Post type. Default page.
116:  * @return WP_Post|null WP_Post on success or null on failure
117:  */
118: function cml_get_page_by_path($page_path, $output = OBJECT, $post_type = array('page')) {
119:     global $wpdb;
120: 
121:     $page_path = rawurlencode(urldecode($page_path));
122:     $page_path = str_replace('%2F', '/', $page_path);
123:     $page_path = str_replace('%20', ' ', $page_path);
124:     $parts = explode( '/', trim( $page_path, '/' ) );
125:     $parts = array_map( 'esc_sql', $parts );
126:     $parts = array_map( 'sanitize_title_for_query', $parts );
127: 
128:     $in_string = "'". implode( "','", $parts ) . "'";
129:     $post_type_sql = implode( "','", $post_type );
130: //     $wpdb->escape_by_ref( $post_type_sql );
131: 
132:     if( empty( $in_string ) ) {
133:       return;
134:     }
135: 
136:     $query = "SELECT ID, post_name, post_parent, post_type FROM $wpdb->posts WHERE post_name IN ($in_string) AND (post_type IN ( '$post_type_sql' ) ) AND post_status = 'publish'";
137:     $pages = $wpdb->get_results( $query, OBJECT_K );
138:     $revparts = array_reverse( $parts );
139: 
140:     $foundid = 0;
141:     foreach ( (array) $pages as $page ) {
142:         if ( $page->post_name == $revparts[0] ) {
143:             $count = 0;
144:             $p = $page;
145: 
146:             while ( $p->post_parent != 0 && isset( $pages[ $p->post_parent ] ) ) {
147:                 $count++;
148:                 $parent = $pages[ $p->post_parent ];
149:                 if ( ! isset( $revparts[ $count ] ) || $parent->post_name != $revparts[ $count ] )
150:                     break;
151:                 $p = $parent;
152:             }
153: 
154:             //if ( $p->post_parent == 0 && $count + 1 == count( $revparts ) && $p->post_name == $revparts[ $count ] ) {
155:             if ( $p->post_parent == 0 && $p->post_name == $revparts[ $count ] ) {
156:               $foundid = $page->ID;
157:               if ( $page->post_type == $post_type )
158:                   break;
159:             }
160:         }
161:     }
162: 
163:     if ( $foundid )
164:         return get_post( $foundid, $output );
165: 
166:     return null;
167: }
168: 
169: /**
170:  * return link of current page in according to selected $language, so if $result != current language
171:  * this function will return its translation link.
172:  *
173:  * @param stdObject $result - language object ( i.e. CMLLanguage::get_default() ) used to translate current link
174:  * @param boolean $linked - true, return linked translation, false return homepage link
175:  * @param boolean $only_existings - return linked post only if it exists, otherwise return blank link
176:  * @param boolean $queried - use get_queried_object_id instead of get_the_ID
177:  *
178:  * return string
179:  */
180: function cml_get_the_link( $result, $linked = true, $only_existings = false, $queried = false ) {
181:   global $wpCeceppaML, $_cml_settings;
182: 
183:   if( $queried && ( cml_is_homepage() || is_search() ) ) { //&& cml_use_static_page() ) {
184:     //current page is homepage?
185:     $link = CMLUtils::get_home_url( $result->cml_language_slug );
186: 
187:     if( is_search() ) {
188:       if( isset( $_GET[ 's' ] ) ) {
189:         $args[ 's' ] = esc_attr( $_GET[ 's' ] );
190:       }
191: 
192:       $args[ 'lang' ] = $result->cml_language_slug;
193: 
194:       $link = add_query_arg( $args, trailingslashit( $link ) );
195:     }
196:   } else {
197:     $GLOBALS[ '_cml_force_home_slug' ] = $result->cml_language_slug;
198:     
199:     //I have to force language to $result one
200:     $wpCeceppaML->force_category_lang( $result->id );
201: 
202:     if( $queried ) {
203:       if( empty( $GLOBALS[ '_cml_get_queried_object' ] ) ) {
204:         $GLOBALS[ '_cml_get_queried_object' ] = get_queried_object();
205:       }
206:       $q = & $GLOBALS[ '_cml_get_queried_object' ];
207:       
208:       $is_category = isset( $q->term_id );
209:       $is_single = isset( $q->ID );
210:       $is_page = $is_single;
211:       $the_id = ( $is_single ) ? $q->ID : 0;
212:       $is_tag = isset( $q->term_taxonomy_id );
213: 
214:       if( empty( $q ) ) {
215:         $is_404 = is_404();
216:       }
217:     } else {
218:       $is_category = is_category();
219:       $is_single = is_single();
220:       $is_page = is_page();
221:       $the_id = get_the_ID();
222:       $is_404 = is_404();
223:       $is_tag = is_tag();
224:     }
225: 
226:     /* Collego la categoria della lingua attuale con quella della linga della bandierina */
227:     $link = "";
228: 
229:     if( ! in_the_loop() ) {
230:       $lang_id = CMLLanguage::get_current_id();
231:     } else
232:       $lang_id = CMLLanguage::get_id_by_post_id( $the_id );
233: 
234:     /*
235:      * I must check that is_category is false, or wp will display 404
236:      * is_single is true also for category and in this case
237:      * the plugin will return wrong link
238:      */
239:     if( ( ( $is_single || $is_page ) ||  $linked ) && ! $is_category ) {
240:       $linked_id = CMLPost::get_translation( $result->id, $the_id );
241: 
242:       if( ! empty( $linked_id ) ) {
243:         $link = get_permalink( $linked_id );
244:       }
245:     }
246: 
247:     if( is_archive() && ! $is_category && ! is_post_type_archive() ) {
248:       global $wp;
249: 
250:       $link = trailingslashit( home_url( $wp->request ) );
251: 
252:       if( CMLUtils::get_url_mode() == PRE_NONE ||
253:           CMLUtils::get_url_mode() == PRE_LANG ) {
254:         $link = add_query_arg( array( "lang" => $result->cml_language_slug ), $link );
255:       }
256:     }
257: 
258:     //Collego le categorie delle varie lingue
259:     if( $is_category ) {
260:       if( $queried && isset( $q->term_id ) ) {
261:         $cat = array( "term_id" => $q->term_id );
262:       } else {
263:         $cat = get_the_category();
264:       }
265: 
266:       if( is_array( $cat ) ) {
267:         $cat_id = ( isset( $cat[ 'term_id' ] ) ) ? $cat[ 'term_id' ] : ( $cat[ count($cat) - 1 ]->term_id );
268: 
269:         //Mi recupererà il link tradotto dal mio plugin ;)
270:         $link = get_category_link( $cat_id );
271:       } //endif;
272:     }
273:     
274:     if( $queried && ( $is_tag && false !== strpos( CMLUtils::get_clean_url(), "/tag/" ) ) ) {
275:       if( ! empty( $q ) ) {
276:         $term_id = $q->term_id;
277:       } else {
278:         $term_id = CMLUtils::_get( "_reverted" );
279:       }
280:       
281:       if( ! empty( $term_id ) ) {
282:         $link = get_tag_link( $term_id );
283:       }
284:     }
285: 
286:     if( is_paged() ) {
287:       $link = add_query_arg( array( "lang" => $result->cml_language_slug ) );
288:     }
289: 
290:     /* Controllo se è stata impostata una pagina statica,
291:     perché così invece di restituire il link dell'articolo collegato
292:     aggiungo il più "bello" ?lang=## alla fine della home.
293: 
294:     Se non ho trovato nesuna traduzione per l'articolo, la bandiera punterà alla homepage
295:     */
296:     if( empty( $link ) && ! $only_existings ) {
297:       if( 1 === CMLUtils::_get( "is_crawler" ) ) {
298:         return;
299:       }
300: 
301:       //If post doesn't exists in current language I'll return the link to default language, if exists :)
302:       if( $_cml_settings[ 'cml_force_languge' ] == 1 ) {
303:         /*
304:          * return translation, if exists :)
305:          */
306:         if( is_single() || is_page() ) {
307:           $l = cml_get_linked_post( $the_id, cml_get_default_language_id() );
308:           //if( ! empty( $l ) ) return get_permalink( $l );
309:         }
310: 
311:         /*
312:          * no translation found, and user choosed to force page to flag language,
313:          * I add parameter "lang=##" to url
314:          */
315:         $link = "http://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
316:         if( CMLPost::get_language_by_id( $the_id ) != $result->id ) {
317:           $link = add_query_arg( array( "lang" => $result->cml_language_slug ), $link );
318:         }
319:       } else {
320:         $link = CMLUtils::get_home_url( $result->cml_language_slug );
321:       }
322: 
323:       if( ( $is_tag || ( isset( $is_404 ) && $is_404 ) ) && CMLUtils::get_url_mode() > PRE_LANG ) {
324:         $clean = CMLUtils::get_clean_url();
325:         $url = CMLUtils::home_url();
326:         
327:         //Change slug in url instead of append ?lang arg
328:         $link = str_replace( $url, "", $clean );
329:         $link = CMLUtils::get_home_url( $result->cml_language_slug ) . $link;
330:       }
331:     }
332:   }
333: 
334:   unset( $GLOBALS[ '_cml_force_home_slug' ] );
335: 
336:   $wpCeceppaML->unset_category_lang();
337: 
338:   return $link;
339: }
340: 
341: /**
342:  * @ignore
343:  * @internal
344:  *
345:  * use static page?
346:  */
347: function cml_use_static_page() {
348:   return (get_option("page_for_posts") > 0) ||
349:       (get_option("page_on_front") > 0);
350: }
351: 
352: /**
353:  * @ignore
354:  * @internal
355:  *
356:  * prepend slug to url
357:  */
358: function prepend_slug_to_url( $slug ) {
359:   global $wpCeceppaML;
360: 
361:   $url = explode( ".", $wpCeceppaML->get_url() );
362:   $url[ 0 ] = $slug;
363:  
364:   return "http://" . join( ".", $url );
365: }
366: 
367: /**
368:  * grab browser language
369:  *
370:  * @return string
371:  */
372: function cml_get_browser_lang() {
373:   if( isset( $GLOBALS[ '_browser_lang' ] ) ) return $GLOBALS[ '_browser_lang' ];
374: 
375:   global $wpdb;
376: 
377:   $browser_langs = explode( ";", $_SERVER['HTTP_ACCEPT_LANGUAGE'] );
378:   $lang = null;
379: 
380:   //Se la lingua del browser coincide con una di quella attuale della pagina, ignoro tutto
381:   foreach( $browser_langs as $blang ) {
382:     @list( $code1, $code2 ) = explode( ",", $blang );
383: 
384:     $locale[] = str_replace( "-", "_", $code1 );
385:     $locale[] = str_replace( "-", "_", $code2 );
386: 
387:     //Per ogni codice che trovo verifico se è gestito, appena ne trovo 1 mi fermo
388:     //Perché il mio browser mi restituisce sia it-IT, che en-EN, quindi mi devo fermare appena trovo un riscontro
389:     //Senno mi ritrovo sempre la lingua en-EN come $browser_langs;
390:     $i = 0;
391:     while( empty( $lang ) && $i < count( $locale ) ) {
392:       $l = $locale[$i];
393:     
394:       if( strlen( $l ) > 2 ) {
395:         $lang = CMLLanguage::get_id_by_locale( $l );
396:       } else {
397:         //Se ho solo 2 caratteri, cerco negli "slug"
398:         $lang = CMLLanguage::get_id_by_slug( $l );
399:       }
400:     
401:       $i++;
402:     } //endwhile;
403: 
404:     if( ! empty ($lang ) ) {
405:       break;
406:     }
407:   }  //endforeach;
408: 
409:   $GLOBALS[ '_browser_lang' ] = $lang;
410: 
411:   return $lang;
412: }
413: 
414: /**
415:  * return post/page notice in selected language
416:  *
417:  * @param sting $lang_slug - language slug
418:  * 
419:  * @return string return translated notice
420:  */
421: function cml_get_notice( $lang ) {
422:   global $wpdb, $wpCeceppaML;
423: 
424:   //$type - type of notice ( post or page )
425:   $type = ( is_single() ) ? "post" : "page";
426: 
427:   $r = CMLTranslations::get( $lang,
428:                             "_notice_$type",
429:                             "N", true, true );
430: 
431:   if( ! empty( $r ) )
432:     return $r;
433:   else
434:     CMLLanguage::get_current()->cml_language;
435: }
436: 
437: /**
438:  * Return flag &lt;ul&gt;&lt;li&gt;....&lt;/li&gt;&lt;/ul&gt; list
439:  *
440:  * @param array $args is parameters list:
441:  *              <ul>
442:  *                <li>
443:  *                  show ( string ) - choose what to display:<br />
444:  *                  <i>default: text</i>
445:  *                </li>
446:  *                <ul>
447:  *                   <li>text: show only language name</li>
448:  *                   <li>slug: show language slug</li>
449:  *                   <li>none: show no text</li>
450:  *               </ul>
451:  *               <li>
452:  *                show_flag ( boolean ) - show flag?<br />
453:  *                <i>default: true</i>
454:  *               </li>
455:  *               <li>size ( string ) - flag size<br />
456:  *                you can use constants:<br />
457:  *                  CML_FLAG_TINY ( 16x11 )<br />
458:  *                  CML_FLAG_SMALL ( 32x23 )<br />
459:  *                  <i>default: CML_FLAG_TINY</i>
460:  *                <ul>
461:  *                  <li>tiny</li>
462:  *                  <li>small</li>
463:  *                </ul>
464:  *               <li>
465:  *                class_name ( string ) - secondary classname to assign to the list
466:  *                <i>default: ""</i>
467:  *                generated &gt;ul&lt; list has primary class "cml_flags", with that parameter you
468:  *                can assign a secondary one.
469:  *               </li>
470:  *               <li>
471:  *                echo ( boolean ) - If true print list, otherwise return string containing generated list<br />
472:  *                <i>default: true</i>
473:  *               </li>
474:  *               <li>
475:  *                linked ( boolean ) - If true flags link to current translation, false will link to homepage<br />
476:  *                <i>default: true</i>
477:  *               </li>
478:  *               <li>
479:  *                only_existings ( boolean ) - show only flags in which current page exists.<br />
480:  *                <i>default: false</i>
481:  *               </li>
482:  *               <li>
483:  *                queried ( boolean ) - use queried object instead of get_the_ID() or other methods, so output will be
484:  *                                      generated in according to main query, not current one.
485:  *                <i>default: false</i>
486:  *               <li>
487:  *              </ul>
488:  */
489: function cml_show_flags( $args ) {
490:   global $wpdb;
491: 
492:   $args = extract( shortcode_atts( array(
493:                       "show" => "text",
494:                       "size" => "tiny",
495:                       "class" => "",
496:                       "image_class" => "",
497:                       "echo" => true,
498:                       "linked" => true,
499:                       "only_existings" => false,
500:                       "sort" => false,
501:                       "queried" => false,
502:                       "show_flag" => true,
503:                       ), $args ) );
504: 
505:   $_cml_settings = & $GLOBALS[ '_cml_settings' ];
506:   $redirect = $_cml_settings[ 'cml_option_redirect' ];
507: 
508:   $results = cml_get_languages( true, false );
509:   $width = ( $size == "tiny" ) ? 16 : 32;
510: 
511:   $r = "<ul class=\"cml_flags $class\">";
512:   
513:   //Post language...
514:   $lang_id = ( ! $sort ) ? -1 : CMLPost::get_language_by_id( get_the_ID() );
515:   $items = array();
516: 
517:   foreach($results as $result) {
518:     $lang = ( $show == "text" ) ? $result->cml_language : "";
519:     $lang = ( $show == "slug" ) ? $result->cml_language_slug : $lang;
520: 
521:     $link = cml_get_the_link( $result, $linked, $only_existings, $queried );
522:     if( empty( $link) ) continue;
523: 
524:     if( $show_flag ) {
525:       $img = "<img class=\"$size $image_class\" src='" . cml_get_flag_by_lang_id( $result->id, $size ) . "' title='$result->cml_language' width=\"$width\"/>";
526:     } else {
527:       $img = "";
528:     }
529: 
530:     $class = ( $result->id == CMLLanguage::get_current_id() ) ? "current" : "";
531:     $li = "<li class=\"$class\"><a href=\"$link\">{$img}{$lang}</a></li>";
532:     if( $sort && is_array( $items ) && $result->id == $lang_id ) {
533:       array_unshift( $items, $li );
534:     } else {
535:       $items[] = $li;
536:     }
537: 
538:   } //endforeach;
539: 
540: 
541:   $r .= join( "\n", $items );
542:   $r .= "</ul>";
543: 
544:   if( $echo ) 
545:     echo $r;
546:   else
547:     return $r;
548: }
549: 
550: /**
551:  * @ignore
552:  * 
553:  * Check if current post is a custom post
554:  */
555: function cml_is_custom_post_type() {
556:   $types = get_post_types( array ( '_builtin' => FALSE ), 'names' );
557:   
558:   if( empty( $types) ) return FALSE;
559: 
560:   $name = get_post_type();
561:   return in_array( $name, $types );
562: }
563: 
564: /**
565:  * @ignore
566:  */
567: function removesmartquotes($content) {
568:   $content = str_replace('&#8220;', '&quot;', $content);
569:   $content = str_replace('&#8221;', '&quot;', $content);
570:   $content = str_replace('&#8216;', '&#39;', $content);
571:   $content = str_replace('&#8217;', '&#39;', $content);
572:  
573:   return $content;
574: }
575: 
576: /**
577:  * @ignore
578:  * 
579:  * http://www.cult-f.net/detect-crawlers-with-php/
580:  *
581:  * Questa funzione server per evitare di reindirizzare o nascondere i post nella lingua differente
582:  * da quella del browser se schi stà visitando il sito è un crawler, al fine di permettere l'indicizzazione di tutti
583:  * gli articoli
584:  *
585:  */
586: function isCrawler()
587: {
588:   global $wp_query;
589:   
590:   if( ! empty( $wp_query ) && $wp_query->is_robots() ) {
591:     CMLUtils::_set( "is_crawler", 1 );
592: 
593:     return true;
594:   }
595:   
596:     $USER_AGENT = $_SERVER['HTTP_USER_AGENT'];
597: 
598:     // to get crawlers string used in function uncomment it
599:     // it is better to save it in string than use implode every time
600:     // global $crawlers
601:     // $crawlers_agents = implode('|',$crawlers);
602:     $crawlers_agents = 'Google|msnbot|Rambler|Yahoo|AbachoBOT|accoona|AcioRobot|ASPSeek|CocoCrawler|Dumbot|FAST-WebCrawler|GeonaBot|Gigabot|Lycos|MSRBOT|Scooter|AltaVista|IDBot|eStyle|Scrubby';
603:  
604:     if ( strpos($crawlers_agents , $USER_AGENT) === false )
605:        return false;
606:     // crawler detected
607:     // you can use it to return its name
608:     /*
609:     else {
610:        return array_search($USER_AGENT, $crawlers);
611:     }
612:     */
613:     return true;
614: }
615: 
616: /**
617:  * return the id of menu to use in according to current language
618:  * return value can be used as wp_nav_menu function.
619:  *
620:  * The plugin automatically switch menu in according to current language,
621:  * you can use this function if automatic switch doesn't works with your theme/framework
622:  * or if you to force a theme.
623:  * 
624:  * @example
625:  * <?php;<br />
626:  *  $menu = cml_get_menu();<br />
627:  *  wp_nav_menu(array('theme_location' => $menu));<br />
628:  * ?>
629:  */
630: function cml_get_menu() {
631:   //Restituisco il nome del menù da utilizzare a seconda della lingua
632:   $lang = cml_get_current_language();
633: 
634:   return "cml_menu_" . $lang->cml_language_slug;
635: }
636: ?>
637: 
API documentation generated by ApiGen 2.8.0