Bin will be removed on June 1, 2014 in favor of http://gist.github.com. Please save all your pastes before then. So long, and thanks for all the fish!×
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<?php
if( false === function_exists('mb_convert_encoding') ) {
    user_error('Sorry, your PHP version does not support multibyte converting. Either upgrade your PHP or load the extension from PECL',E_USER_ERROR);
}
 
/**
 * @copyright       Copyright (c) 2007 Enovo
 * @author          Christian Winther
 * @link            http://www.enovo.dk
 * @filesource
 * @since           1.0
 * @package         sw.model.behaviors
 * @modifiedby      $LastChangedBy:$
 * @lastmodified    $Date:$
 * @svn             $Id:$
 */
class MultibyteBehavior extends ModelBehavior {
    /**
     * Default settings for our model
     *
     * 'save' is the conversion the behavior should use to store data in db
     *      can be 'false', meaning no conversion will happen when saving data
     *
     * 'find' is the output the behavior should use ( to screen )
     *      can be 'false', means no conversion will happen when reading data
     *
     * 'convertFrom' can either be
     *      - auto :
     *          Attemps to auto detect the source encoding
     *      - array('UTF-8',...')
     *          A list of possible encodings to try
     *
     * 'primaryOnly' is if 'finder' should only convert if its the primary model
     *
     *
     * @var array
     */
    var $defaultSettings = array(
        'save' => array(
            'convertTo'     => 'UTF-8',
            'convertFrom'   => 'auto'
        ),
        'find' => array(
            'convertTo'     => 'ISO-8859-15',
            'convertFrom'   => 'auto',
            'primaryOnly'   => true
        )
    );
 
    /**
     * List of valid encodings
     *
     * @var array
     */
    var $validEncodings;
 
    /**
     * List of model settings
     *
     * @var array
     */
    var $settings = array();
 
    /**
     * Setup callback
     *
     * @param AppModel $model
     * @param array $config
     */
    function setup(&$model, $config = array() ) {
        // Check if we have a list of all valid encodings supported by PHP
        if( true === empty( $this->validEncodings ) ) {
            // Build the list of valid encodings
            $this->validEncodings = mb_list_encodings();
        }
        // Merge user settings with default
        $settings = am($this->defaultSettings, $config );
 
        // Check if the target encoding when saving is supported
        if( false === empty( $settings['save']['convertTo'] ) && false === array_search( $settings['save']['convertTo'], $this->validEncodings ) ) {
            user_error('Invalid target encoding for "'.$model->name.'::save" - '. $settings['save']['convertTo'] .' is not valid!', E_USER_ERROR );
        }
 
        // Check if the target encoding for reading is supported
        elseif ( false === empty( $settings['find']['convertTo'] ) && false === array_search( $settings['find']['convertTo'], $this->validEncodings ) ) {
            user_error('Invalid target encoding for "'.$model->name.'::find" - '. $settings['find']['convertTo'] .' is not valid!', E_USER_ERROR );
        }
        else
        {
            $this->settings[ $model->name ] = $settings;
        }
    }
 
    /**
     * Callback for when model is saving
     *
     * @param AppModel $model
     */
    function beforeSave(&$model)
    {
        $settings = $this->settings[ $model->name ]['save'];
 
        // Check if we should convert data when saving
        if( true === is_bool($settings) && false === $settings ) {
            return true;
        }
        $model->data = $this->doConversion( $model->data, $settings );
        return true;
    }
 
    /**
     * Callback for when model is reading
     *
     * @param AppModel $model
     * @param array $results
     * @param boolean $primary
     */
    function afterFind(&$model, $results, $primary)
    {
        $settings = $this->settings[ $model->name ]['find'];
        if( true === empty($settings) || ( true === $settings['primaryOnly'] && true !== $primary ) ) {
            return $results;
        }
        return $this->doConversion( $results, $settings );
    }
 
    /**
     * Do the converting of encoding on string, recursive
     *
     * @param array $data
     * @param array $settings
     * @return array
     */
    function doConversion( $data, $settings ) {
        if( true === is_array( $data ) ) {
            if( 0 === count( $data ) ) {
               return $data;
            }
            foreach ( $data AS $key => $name ) {
                $data[ $key ] = $this->doConversion( $name, $settings );
            }
            return $data;
        }
        return mb_convert_encoding( $data, $settings['convertTo'], $settings['convertFrom'] );
    }
}