Advertisement
Guest User

SlugBehavior.php

a guest
Jul 4th, 2013
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 16.23 KB | None | 0 0
  1. <?php
  2.  
  3. class SlugBehavior extends ModelBehavior {
  4.  
  5.     /**
  6.      * Default model settings
  7.      */
  8.     var $defaultSettings = array('field' => 'name', 'slug_field' => 'slug', 'primary_key' => 'id', 'replacement' => '-', 'DBcheck' => false, 'set_func'=>'');
  9.  
  10.     /**
  11.      * Initiate behaviour for the model using settings.
  12.      *
  13.      * @param object $model    Model using the behaviour
  14.      * @param array $settings    Settings to override for model.
  15.      *
  16.      * @access public
  17.      */
  18.     function setup(Model $model, $settings = array()) {
  19.         $field = $this->defaultSettings['field'];
  20.         $slug_field = $this->defaultSettings['slug_field'];
  21.         $primary_key = $this->defaultSettings['primary_key'];
  22.         $replacement = $this->defaultSettings['replacement'];
  23.  
  24.         if (!empty($settings['field'])) {
  25.             $field = $settings['field'];
  26.         }
  27.  
  28.         if (!empty($settings['slug_field'])) {
  29.             $slug_field = $settings['slug_field'];
  30.         }
  31.  
  32.         if (!empty($settings['primary_key'])) {
  33.             $primary_key = $settings['primary_key'];
  34.         }
  35.  
  36.  
  37.         if (!empty($settings['replacement'])) {
  38.             $replacement = $settings['replacement'];
  39.         }
  40.         $this->settings['replacement'] = $replacement;
  41.        
  42.         if (!empty($settings['DBcheck'])) {
  43.             $this->settings['DBcheck'] = $settings['DBcheck'];
  44.         }        
  45.  
  46.         if (!empty($settings['set_func'])) {
  47.             $this->settings['set_func'] = $settings['set_func'];
  48.         }
  49.  
  50.         if ($model->hasField($field)) {
  51.             $this->settings[$model->name]['field'] = $field;
  52.         }
  53.  
  54.         if ($model->hasField($slug_field)) {
  55.             $this->settings[$model->name]['slug_field'] = $slug_field;
  56.         }
  57.  
  58.         if ($model->hasField($primary_key)) {
  59.             $this->settings[$model->name]['primary_key'] = $primary_key;
  60.         }
  61.     }
  62.  
  63.     function seems_utf8($str) {
  64.         $length = strlen($str);
  65.         for ($i = 0; $i < $length; $i++) {
  66.             $c = ord($str[$i]);
  67.             if ($c < 0x80)
  68.                 $n = 0;# 0bbbbbbb
  69.            elseif (($c & 0xE0) == 0xC0)
  70.                 $n = 1;# 110bbbbb
  71.            elseif (($c & 0xF0) == 0xE0)
  72.                 $n = 2;# 1110bbbb
  73.            elseif (($c & 0xF8) == 0xF0)
  74.                 $n = 3;# 11110bbb
  75.            elseif (($c & 0xFC) == 0xF8)
  76.                 $n = 4;# 111110bb
  77.            elseif (($c & 0xFE) == 0xFC)
  78.                 $n = 5;# 1111110b
  79.            else
  80.                 return false;# Does not match any model
  81.            for ($j = 0; $j < $n; $j++) { # n bytes matching 10bbbbbb follow ?
  82.                if ((++$i == $length) || ((ord($str[$i]) & 0xC0) != 0x80))
  83.                     return false;
  84.             }
  85.         }
  86.         return true;
  87.     }
  88.  
  89.     function remove_accents($string) {
  90.         if (!preg_match('/[\x80-\xff]/', $string))
  91.             return $string;
  92.  
  93.         if ($this->seems_utf8($string)) {
  94.             $chars = array(
  95.                 // Decompositions for Latin-1 Supplement
  96.                 chr(195) . chr(128) => 'A', chr(195) . chr(129) => 'A',
  97.                 chr(195) . chr(130) => 'A', chr(195) . chr(131) => 'A',
  98.                 chr(195) . chr(132) => 'A', chr(195) . chr(133) => 'A',
  99.                 chr(195) . chr(135) => 'C', chr(195) . chr(136) => 'E',
  100.                 chr(195) . chr(137) => 'E', chr(195) . chr(138) => 'E',
  101.                 chr(195) . chr(139) => 'E', chr(195) . chr(140) => 'I',
  102.                 chr(195) . chr(141) => 'I', chr(195) . chr(142) => 'I',
  103.                 chr(195) . chr(143) => 'I', chr(195) . chr(145) => 'N',
  104.                 chr(195) . chr(146) => 'O', chr(195) . chr(147) => 'O',
  105.                 chr(195) . chr(148) => 'O', chr(195) . chr(149) => 'O',
  106.                 chr(195) . chr(150) => 'O', chr(195) . chr(153) => 'U',
  107.                 chr(195) . chr(154) => 'U', chr(195) . chr(155) => 'U',
  108.                 chr(195) . chr(156) => 'U', chr(195) . chr(157) => 'Y',
  109.                 chr(195) . chr(159) => 's', chr(195) . chr(160) => 'a',
  110.                 chr(195) . chr(161) => 'a', chr(195) . chr(162) => 'a',
  111.                 chr(195) . chr(163) => 'a', chr(195) . chr(164) => 'a',
  112.                 chr(195) . chr(165) => 'a', chr(195) . chr(167) => 'c',
  113.                 chr(195) . chr(168) => 'e', chr(195) . chr(169) => 'e',
  114.                 chr(195) . chr(170) => 'e', chr(195) . chr(171) => 'e',
  115.                 chr(195) . chr(172) => 'i', chr(195) . chr(173) => 'i',
  116.                 chr(195) . chr(174) => 'i', chr(195) . chr(175) => 'i',
  117.                 chr(195) . chr(177) => 'n', chr(195) . chr(178) => 'o',
  118.                 chr(195) . chr(179) => 'o', chr(195) . chr(180) => 'o',
  119.                 chr(195) . chr(181) => 'o', chr(195) . chr(182) => 'o',
  120.                 chr(195) . chr(182) => 'o', chr(195) . chr(185) => 'u',
  121.                 chr(195) . chr(186) => 'u', chr(195) . chr(187) => 'u',
  122.                 chr(195) . chr(188) => 'u', chr(195) . chr(189) => 'y',
  123.                 chr(195) . chr(191) => 'y',
  124.                 // Decompositions for Latin Extended-A
  125.                 chr(196) . chr(128) => 'A', chr(196) . chr(129) => 'a',
  126.                 chr(196) . chr(130) => 'A', chr(196) . chr(131) => 'a',
  127.                 chr(196) . chr(132) => 'A', chr(196) . chr(133) => 'a',
  128.                 chr(196) . chr(134) => 'C', chr(196) . chr(135) => 'c',
  129.                 chr(196) . chr(136) => 'C', chr(196) . chr(137) => 'c',
  130.                 chr(196) . chr(138) => 'C', chr(196) . chr(139) => 'c',
  131.                 chr(196) . chr(140) => 'C', chr(196) . chr(141) => 'c',
  132.                 chr(196) . chr(142) => 'D', chr(196) . chr(143) => 'd',
  133.                 chr(196) . chr(144) => 'D', chr(196) . chr(145) => 'd',
  134.                 chr(196) . chr(146) => 'E', chr(196) . chr(147) => 'e',
  135.                 chr(196) . chr(148) => 'E', chr(196) . chr(149) => 'e',
  136.                 chr(196) . chr(150) => 'E', chr(196) . chr(151) => 'e',
  137.                 chr(196) . chr(152) => 'E', chr(196) . chr(153) => 'e',
  138.                 chr(196) . chr(154) => 'E', chr(196) . chr(155) => 'e',
  139.                 chr(196) . chr(156) => 'G', chr(196) . chr(157) => 'g',
  140.                 chr(196) . chr(158) => 'G', chr(196) . chr(159) => 'g',
  141.                 chr(196) . chr(160) => 'G', chr(196) . chr(161) => 'g',
  142.                 chr(196) . chr(162) => 'G', chr(196) . chr(163) => 'g',
  143.                 chr(196) . chr(164) => 'H', chr(196) . chr(165) => 'h',
  144.                 chr(196) . chr(166) => 'H', chr(196) . chr(167) => 'h',
  145.                 chr(196) . chr(168) => 'I', chr(196) . chr(169) => 'i',
  146.                 chr(196) . chr(170) => 'I', chr(196) . chr(171) => 'i',
  147.                 chr(196) . chr(172) => 'I', chr(196) . chr(173) => 'i',
  148.                 chr(196) . chr(174) => 'I', chr(196) . chr(175) => 'i',
  149.                 chr(196) . chr(176) => 'I', chr(196) . chr(177) => 'i',
  150.                 chr(196) . chr(178) => 'IJ', chr(196) . chr(179) => 'ij',
  151.                 chr(196) . chr(180) => 'J', chr(196) . chr(181) => 'j',
  152.                 chr(196) . chr(182) => 'K', chr(196) . chr(183) => 'k',
  153.                 chr(196) . chr(184) => 'k', chr(196) . chr(185) => 'L',
  154.                 chr(196) . chr(186) => 'l', chr(196) . chr(187) => 'L',
  155.                 chr(196) . chr(188) => 'l', chr(196) . chr(189) => 'L',
  156.                 chr(196) . chr(190) => 'l', chr(196) . chr(191) => 'L',
  157.                 chr(197) . chr(128) => 'l', chr(197) . chr(129) => 'L',
  158.                 chr(197) . chr(130) => 'l', chr(197) . chr(131) => 'N',
  159.                 chr(197) . chr(132) => 'n', chr(197) . chr(133) => 'N',
  160.                 chr(197) . chr(134) => 'n', chr(197) . chr(135) => 'N',
  161.                 chr(197) . chr(136) => 'n', chr(197) . chr(137) => 'N',
  162.                 chr(197) . chr(138) => 'n', chr(197) . chr(139) => 'N',
  163.                 chr(197) . chr(140) => 'O', chr(197) . chr(141) => 'o',
  164.                 chr(197) . chr(142) => 'O', chr(197) . chr(143) => 'o',
  165.                 chr(197) . chr(144) => 'O', chr(197) . chr(145) => 'o',
  166.                 chr(197) . chr(146) => 'OE', chr(197) . chr(147) => 'oe',
  167.                 chr(197) . chr(148) => 'R', chr(197) . chr(149) => 'r',
  168.                 chr(197) . chr(150) => 'R', chr(197) . chr(151) => 'r',
  169.                 chr(197) . chr(152) => 'R', chr(197) . chr(153) => 'r',
  170.                 chr(197) . chr(154) => 'S', chr(197) . chr(155) => 's',
  171.                 chr(197) . chr(156) => 'S', chr(197) . chr(157) => 's',
  172.                 chr(197) . chr(158) => 'S', chr(197) . chr(159) => 's',
  173.                 chr(197) . chr(160) => 'S', chr(197) . chr(161) => 's',
  174.                 chr(197) . chr(162) => 'T', chr(197) . chr(163) => 't',
  175.                 chr(197) . chr(164) => 'T', chr(197) . chr(165) => 't',
  176.                 chr(197) . chr(166) => 'T', chr(197) . chr(167) => 't',
  177.                 chr(197) . chr(168) => 'U', chr(197) . chr(169) => 'u',
  178.                 chr(197) . chr(170) => 'U', chr(197) . chr(171) => 'u',
  179.                 chr(197) . chr(172) => 'U', chr(197) . chr(173) => 'u',
  180.                 chr(197) . chr(174) => 'U', chr(197) . chr(175) => 'u',
  181.                 chr(197) . chr(176) => 'U', chr(197) . chr(177) => 'u',
  182.                 chr(197) . chr(178) => 'U', chr(197) . chr(179) => 'u',
  183.                 chr(197) . chr(180) => 'W', chr(197) . chr(181) => 'w',
  184.                 chr(197) . chr(182) => 'Y', chr(197) . chr(183) => 'y',
  185.                 chr(197) . chr(184) => 'Y', chr(197) . chr(185) => 'Z',
  186.                 chr(197) . chr(186) => 'z', chr(197) . chr(187) => 'Z',
  187.                 chr(197) . chr(188) => 'z', chr(197) . chr(189) => 'Z',
  188.                 chr(197) . chr(190) => 'z', chr(197) . chr(191) => 's',
  189.                 // Euro Sign
  190.                 chr(226) . chr(130) . chr(172) => 'E',
  191.                 // GBP (Pound) Sign
  192.                 chr(194) . chr(163) => '');
  193.  
  194.             $string = strtr($string, $chars);
  195.         } else {
  196.             // Assume ISO-8859-1 if not UTF-8
  197.             $chars['in'] = chr(128) . chr(131) . chr(138) . chr(142) . chr(154) . chr(158)
  198.                     . chr(159) . chr(162) . chr(165) . chr(181) . chr(192) . chr(193) . chr(194)
  199.                     . chr(195) . chr(196) . chr(197) . chr(199) . chr(200) . chr(201) . chr(202)
  200.                     . chr(203) . chr(204) . chr(205) . chr(206) . chr(207) . chr(209) . chr(210)
  201.                     . chr(211) . chr(212) . chr(213) . chr(214) . chr(216) . chr(217) . chr(218)
  202.                     . chr(219) . chr(220) . chr(221) . chr(224) . chr(225) . chr(226) . chr(227)
  203.                     . chr(228) . chr(229) . chr(231) . chr(232) . chr(233) . chr(234) . chr(235)
  204.                     . chr(236) . chr(237) . chr(238) . chr(239) . chr(241) . chr(242) . chr(243)
  205.                     . chr(244) . chr(245) . chr(246) . chr(248) . chr(249) . chr(250) . chr(251)
  206.                     . chr(252) . chr(253) . chr(255);
  207.  
  208.             $chars['out'] = "EfSZszYcYuAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy";
  209.  
  210.             $string = strtr($string, $chars['in'], $chars['out']);
  211.             $double_chars['in'] = array(chr(140), chr(156), chr(198), chr(208), chr(222), chr(223), chr(230), chr(240), chr(254));
  212.             $double_chars['out'] = array('OE', 'oe', 'AE', 'DH', 'TH', 'ss', 'ae', 'dh', 'th');
  213.             $string = str_replace($double_chars['in'], $double_chars['out'], $string);
  214.         }
  215.  
  216.         return $string;
  217.     }
  218.  
  219.     function utf8_uri_encode($utf8_string, $length = 0) {
  220.         $unicode = '';
  221.         $values = array();
  222.         $num_octets = 1;
  223.         $unicode_length = 0;
  224.  
  225.         $string_length = strlen($utf8_string);
  226.         for ($i = 0; $i < $string_length; $i++) {
  227.  
  228.             $value = ord($utf8_string[$i]);
  229.  
  230.             if ($value < 128) {
  231.                 if ($length && ( $unicode_length >= $length ))
  232.                     break;
  233.                 $unicode .= chr($value);
  234.                 $unicode_length++;
  235.             } else {
  236.                 if (count($values) == 0)
  237.                     $num_octets = ( $value < 224 ) ? 2 : 3;
  238.  
  239.                 $values[] = $value;
  240.  
  241.                 if ($length && ( $unicode_length + ($num_octets * 3) ) > $length)
  242.                     break;
  243.                 if (count($values) == $num_octets) {
  244.                     if ($num_octets == 3) {
  245.                         $unicode .= '%' . dechex($values[0]) . '%' . dechex($values[1]) . '%' . dechex($values[2]);
  246.                         $unicode_length += 9;
  247.                     } else {
  248.                         $unicode .= '%' . dechex($values[0]) . '%' . dechex($values[1]);
  249.                         $unicode_length += 6;
  250.                     }
  251.  
  252.                     $values = array();
  253.                     $num_octets = 1;
  254.                 }
  255.             }
  256.         }
  257.  
  258.         return $unicode;
  259.     }
  260.  
  261.     function sanitize_title_with_dashes($title) {
  262.         $title = strip_tags($title);
  263.         // Preserve escaped octets.
  264.         $title = preg_replace('|%([a-fA-F0-9][a-fA-F0-9])|', '---$1---', $title);
  265.         // Remove percent signs that are not part of an octet.
  266.         $title = str_replace('%', '', $title);
  267.         // Restore octets.
  268.         $title = preg_replace('|---([a-fA-F0-9][a-fA-F0-9])---|', '%$1', $title);
  269.  
  270.         $title = $this->remove_accents($title);
  271.         if ($this->seems_utf8($title)) {
  272.             if (function_exists('mb_strtolower')) {
  273.                 $title = mb_strtolower($title, 'UTF-8');
  274.             }
  275.             $title = $this->utf8_uri_encode($title, 200);
  276.         }
  277.  
  278.         $title = strtolower($title);
  279.         $title = preg_replace('/&.+?;/', '', $title); // kill entities
  280.         $title = str_replace('.', '-', $title);
  281.         $title = preg_replace('/[^%a-z0-9 _-]/', '', $title);
  282.         $title = preg_replace('/\s+/', '-', $title);
  283.         $title = preg_replace('|-+|', '-', $title);
  284.         $title = trim($title, '-');
  285.  
  286.         return $title;
  287.     }
  288.  
  289.     //generate slug
  290.     function _slug($title) {
  291.         $this->autoRender = false;
  292.         if (empty($this->settings))
  293.             $this->settings = $this->defaultSettings;
  294.         $title = trim($title);
  295.         if ($title != null) {
  296.             App::import('Vendor', 'TreeMenu.unicode2ascii');
  297.             $replacement = $this->settings['replacement'];
  298.             $slug = unicode2ascii::utf8_to_ascii($title, $replacement);
  299.             $slug = $this->sanitize_title_with_dashes($slug);
  300.             return $slug;
  301.             //$slug = Inflector::slug($title, $replacement);
  302.             //$slug = preg_replace('/[_]+/',$replacement,$slug);
  303.             //$slug = preg_replace('/['.$replacement.']+/',$replacement,$slug);
  304.             //return $slug;
  305.         }
  306.         return false;
  307.     }
  308.  
  309.     /**
  310.      *
  311.      * @access public
  312.      */
  313.     function beforeSave(Model $model) {
  314.         if ($this->settings[$model->name]) {
  315.             $field = $this->settings[$model->name]['field'];
  316.             $slug_field = $this->settings[$model->name]['slug_field'];
  317.             $replacement = $this->settings['replacement'];
  318.             $primary_key = $this->settings[$model->name]['primary_key'];
  319.             $DBCheck = (isset($this->settings['DBcheck'])) ? $this->settings['DBcheck'] : $this->defaultSettings['DBcheck'];
  320.             if(isset($model->data[$model->name][$field])){
  321.                 $slug = Inflector::slug(strtolower($this->_slug(trim($model->data[$model->name][$field]))), $replacement);
  322.                 if($DBCheck){
  323.                     $id = (isset($model->data[$model->name][$primary_key])) ? $model->data[$model->name][$primary_key] : null;
  324.                     $conditions = array($model->name.'.'.$slug_field=>$slug);
  325.                     if($id){
  326.                         $conditions[$model->name.'.'.$primary_key.' <>'] =  $id;
  327.                     }
  328.                    
  329.                     $slugCheck = $model->find('count', array('conditions'=>$conditions));
  330.                     if(intval($slugCheck) > 0){
  331.                         $slug = $slug.$replacement.uniqid();
  332.                     }
  333.                 }
  334.                 $model->data[$model->name][$slug_field] = $slug;
  335.                 $set_func = (isset($this->settings['set_func'])) ? $this->settings['set_func'] : false;;
  336.                 if($set_func){
  337.                     $model->$set_func($slug);
  338.                 }
  339.             }
  340.         }
  341.     }
  342. }
  343.  
  344. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement