Projet

Général

Profil

Paste
Télécharger (16,5 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / libraries / iCalcreator-2.22.1 / lib / iCalBase.class.php @ bad93dab

1
<?php
2
/*********************************************************************************/
3
/**
4
 *
5
 * iCalcreator, a PHP rfc2445/rfc5545 solution.
6
 *
7
 * @copyright Copyright (c) 2007-2015 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
8
 * @link      http://kigkonsult.se/iCalcreator/index.php
9
 * @license   http://kigkonsult.se/downloads/dl.php?f=LGPL
10
 * @package   iCalcreator
11
 * @version   2.22
12
 */
13
/**
14
 * This library is free software; you can redistribute it and/or
15
 * modify it under the terms of the GNU Lesser General Public
16
 * License as published by the Free Software Foundation; either
17
 * version 2.1 of the License, or (at your option) any later version.
18
 *
19
 * This library is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22
 * Lesser General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU Lesser General Public
25
 * License along with this library; if not, write to the Free Software
26
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27
 */
28
/*********************************************************************************/
29
/**
30
 * iCalcreator base class
31
 *
32
 * properties and functions shared by vcalendar and calendarComponents
33
 *
34
 * @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
35
 * @since 2.21.11 - 2015-03-31
36
 */
37
abstract class iCalBase {
38
/**
39
 *  @var array component property X-property value
40
 *  @access protected
41
 */
42
  protected $xprop;
43
/**  @var array container for sub-components */
44
  public $components;
45
/**  @var array $unparsed  calendar/components in 'raw' text... */
46
  public $unparsed;
47
/**
48
 *  @var bool   $allowEmpty  config variable
49
 *  @var string $language    config variable
50
 *  @var string $nl          config variable
51
 *  @var string $unique_id   config variable
52
 *  @var string $format      config variable
53
 *  @var string $dtzid       config variable
54
 *  @access protected
55
 */
56
  protected $allowEmpty;
57
  protected $language;
58
  protected $nl;
59
  protected $unique_id;
60
  protected $format;
61
  protected $dtzid;
62
/**
63
 *  @var string $componentStart1     valendar/component internal variable
64
 *  @var string $componentStart2     valendar/component internal variable
65
 *  @var string $componentEnd1       valendar/component internal variable
66
 *  @var string $componentEnd2       valendar/component internal variable
67
 *  @var string $elementStart1       valendar/component internal variable
68
 *  @var string $elementStart2       valendar/component internal variable
69
 *  @var string $elementEnd1         valendar/component internal variable
70
 *  @var string $elementEnd2         valendar/component internal variable
71
 *  @var string $intAttrDelimiter    valendar/component internal variable
72
 *  @var string $attributeDelimiter  valendar/component internal variable
73
 *  @var string $valueInit           valendar/component internal variable
74
 *  @access protected
75
 */
76
  protected $componentStart1;
77
  protected $componentStart2;
78
  protected $componentEnd1;
79
  protected $componentEnd2;
80
  protected $elementStart1;
81
  protected $elementStart2;
82
  protected $elementEnd1;
83
  protected $elementEnd2;
84
  protected $intAttrDelimiter;
85
  protected $attributeDelimiter;
86
  protected $valueInit;
87
/**
88
 *  @var array $xcaldecl  xCal declaration container
89
 *  @access protected
90
 */
91
  protected $xcaldecl;
92
/**
93
 * Property Name: x-prop
94
 */
95
/**
96
 * creates formatted output for calendar/component property x-prop
97
 *
98
 * @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
99
 * @since 2.21.11 - 2015-03-31
100
 * @uses iCalBase::$xprop
101
 * @uses vcalendar::getConfig()
102
 * @uses calendarComponent::getConfig()
103
 * @uses iCalBase::_createElement()
104
 * @uses iCalBase::_createParams()
105
 * @uses iCalUtilityFunctions::_strrep()
106
 * @uses iCalBase::$format
107
 * @uses iCalBase::$nl
108
 * @return string
109
 */
110
  public function createXprop() {
111
    if( empty( $this->xprop ) || !is_array( $this->xprop )) return FALSE;
112
    $output        = null;
113
    foreach( $this->xprop as $label => $xpropPart ) {
114
      if( ! isset( $xpropPart['value']) || ( empty( $xpropPart['value'] ) && !is_numeric( $xpropPart['value'] ))) {
115
        if( $this->getConfig( 'allowEmpty' ))
116
          $output .= $this->_createElement( $label );
117
        continue;
118
      }
119
      $attributes  = $this->_createParams( $xpropPart['params'], array( 'LANGUAGE' ));
120
      if( is_array( $xpropPart['value'] )) {
121
        foreach( $xpropPart['value'] as $pix => $theXpart )
122
          $xpropPart['value'][$pix] = iCalUtilityFunctions::_strrep( $theXpart, $this->format, $this->nl );
123
        $xpropPart['value']  = implode( ',', $xpropPart['value'] );
124
      }
125
      else
126
        $xpropPart['value'] = iCalUtilityFunctions::_strrep( $xpropPart['value'], $this->format, $this->nl );
127
      $output     .= $this->_createElement( $label, $attributes, $xpropPart['value'] );
128
    }
129
    return $output;
130
  }
131
/**
132
 * set calendar property x-prop
133
 *
134
 * @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
135
 * @since 2.21.11 - 2015-03-31
136
 * @param string $label
137
 * @param string $value
138
 * @param array $params optional
139
 * @uses vcalendar::getConfig()
140
 * @uses iCalUtilityFunctions::_setParams()
141
 * @uses iCalBase::$xprop
142
 * @return bool
143
 */
144
  public function setXprop( $label, $value, $params=FALSE ) {
145
    if( empty( $label ))
146
      return FALSE;
147
    $label = strtoupper( $label );
148
    if( 'X-' != substr( $label, 0, 2 ))
149
      return FALSE;
150
    if( empty( $value ) && !is_numeric( $value )) if( $this->getConfig( 'allowEmpty' )) $value = ''; else return FALSE;
151
    $xprop           = array( 'value' => $value );
152
    $xprop['params'] = iCalUtilityFunctions::_setParams( $params );
153
    if( ! is_array( $this->xprop ))
154
      $this->xprop = array();
155
    $this->xprop[$label] = $xprop;
156
    return TRUE;
157
  }
158
/**
159
 * create element format parts
160
 *
161
 * @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
162
 * @since 2.21.11 - 2015-03-31
163
 * @uses iCalBase::$format
164
 * @uses iCalBase::$objName
165
 * @uses iCalBase::$componentStart1
166
 * @uses iCalBase::$elementStart1
167
 * @uses iCalBase::$componentStart2
168
 * @uses iCalBase::$elementStart2
169
 * @uses iCalBase::$componentEnd1
170
 * @uses iCalBase::$elementEnd1
171
 * @uses iCalBase::$componentEnd2
172
 * @uses iCalBase::$elementEnd2
173
 * @uses iCalBase::$nl;
174
 * @uses iCalBase::$intAttrDelimiter
175
 * @uses iCalBase::$attributeDelimiter
176
 * @uses iCalBase::$valueInit
177
 * @return bool
178
 */
179
  function _createFormat() {
180
    switch( $this->format ) {
181
      case 'xcal':
182
        $this->componentStart1    = $this->elementStart1 = '<';
183
        $this->componentStart2    = $this->elementStart2 = '>';
184
        $this->componentEnd1      = $this->elementEnd1   = '</';
185
        $this->componentEnd2      = $this->elementEnd2   = '>'.$this->nl;
186
        $this->intAttrDelimiter   = '<!-- -->';
187
        $this->attributeDelimiter = $this->nl;
188
        $this->valueInit          = null;
189
        break;
190
      default:
191
        $this->componentStart1    = 'BEGIN:';
192
        $this->componentStart2    = null;
193
        $this->componentEnd1      = 'END:';
194
        $this->componentEnd2      = $this->nl;
195
        $this->elementStart1      = null;
196
        $this->elementStart2      = null;
197
        $this->elementEnd1        = null;
198
        $this->elementEnd2        = $this->nl;
199
        $this->intAttrDelimiter   = '<!-- -->';
200
        $this->attributeDelimiter = ';';
201
        $this->valueInit          = ':';
202
        break;
203
    }
204
    return TRUE;
205
  }
206
/**
207
 * creates formatted output for calendar component property
208
 *
209
 * @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
210
 * @since 2.21.11 - 2015-03-31
211
 * @param string $label property name
212
 * @param string $attributes property attributes
213
 * @param string $content property content (optional)
214
 * @uses iCalBase::$format
215
 * @uses iCalBase::$elementStart1
216
 * @uses iCalBase::$xcaldecl
217
 * @uses iCalBase::$intAttrDelimiter
218
 * @uses iCalBase::$attributeDelimiter
219
 * @uses iCalBase::_createElement()
220
 * @uses iCalBase::$elementStart2
221
 * @uses iCalBase::$nl
222
 * @uses iCalBase::$valueInit
223
 * @uses iCalUtilityFunctions::_size75()
224
 * @uses iCalBase::$elementEnd1
225
 * @uses iCalBase::$elementEnd2
226
 * @access protected
227
 * @return string
228
 */
229
  protected function _createElement( $label, $attributes=null, $content=FALSE ) {
230
    switch( $this->format ) {
231
      case 'xcal':
232
        $label = strtolower( $label );
233
        break;
234
      default:
235
        $label = strtoupper( $label );
236
        break;
237
    }
238
    $output = $this->elementStart1.$label;
239
    $categoriesAttrLang = null;
240
    $attachInlineBinary = FALSE;
241
    $attachfmttype      = null;
242
    if (( 'xcal' == $this->format) && ( 'x-' == substr( $label, 0, 2 ))) {
243
      $this->xcaldecl[] = array( 'xmldecl'  => 'ELEMENT'
244
                               , 'ref'      => $label
245
                               , 'type2'    => '(#PCDATA)' );
246
    }
247
    if( !empty( $attributes ))  {
248
      $attributes  = trim( $attributes );
249
      if ( 'xcal' == $this->format ) {
250
        $attributes2 = explode( $this->intAttrDelimiter, $attributes );
251
        $attributes  = null;
252
        foreach( $attributes2 as $aix => $attribute ) {
253
          $attrKVarr = explode( '=', $attribute );
254
          if( empty( $attrKVarr[0] ))
255
            continue;
256
          if( !isset( $attrKVarr[1] )) {
257
            $attrValue = $attrKVarr[0];
258
            $attrKey   = $aix;
259
          }
260
          elseif( 2 == count( $attrKVarr)) {
261
            $attrKey   = strtolower( $attrKVarr[0] );
262
            $attrValue = $attrKVarr[1];
263
          }
264
          else {
265
            $attrKey   = strtolower( $attrKVarr[0] );
266
            unset( $attrKVarr[0] );
267
            $attrValue = implode( '=', $attrKVarr );
268
          }
269
          if(( 'attach' == $label ) && ( in_array( $attrKey, array( 'fmttype', 'encoding', 'value' )))) {
270
            $attachInlineBinary = TRUE;
271
            if( 'fmttype' == $attrKey )
272
              $attachfmttype = $attrKey.'='.$attrValue;
273
            continue;
274
          }
275
          elseif(( 'categories' == $label ) && ( 'language' == $attrKey ))
276
            $categoriesAttrLang = $attrKey.'='.$attrValue;
277
          else {
278
            $attributes .= ( empty( $attributes )) ? ' ' : $this->attributeDelimiter.' ';
279
            $attributes .= ( !empty( $attrKey )) ? $attrKey.'=' : null;
280
            if(( '"' == substr( $attrValue, 0, 1 )) && ( '"' == substr( $attrValue, -1 ))) {
281
              $attrValue = substr( $attrValue, 1, ( strlen( $attrValue ) - 2 ));
282
              $attrValue = str_replace( '"', '', $attrValue );
283
            }
284
            $attributes .= '"'.htmlspecialchars( $attrValue ).'"';
285
          }
286
        }
287
      }
288
      else {
289
        $attributes = str_replace( $this->intAttrDelimiter, $this->attributeDelimiter, $attributes );
290
      }
291
    }
292
    if(( 'xcal' == $this->format) &&
293
       ((( 'attach' == $label ) && !$attachInlineBinary ) || ( in_array( $label, array( 'tzurl', 'url' ))))) {
294
      $pos = strrpos( $content, "/" );
295
      $docname = ( $pos !== false) ? substr( $content, (1 - strlen( $content ) + $pos )) : $content;
296
      $this->xcaldecl[] = array( 'xmldecl'  => 'ENTITY'
297
                               , 'uri'      => $docname
298
                               , 'ref'      => 'SYSTEM'
299
                               , 'external' => $content
300
                               , 'type'     => 'NDATA'
301
                               , 'type2'    => 'BINERY' );
302
      $attributes .= ( empty( $attributes )) ? ' ' : $this->attributeDelimiter.' ';
303
      $attributes .= 'uri="'.$docname.'"';
304
      $content = null;
305
      if( 'attach' == $label ) {
306
        $attributes = str_replace( $this->attributeDelimiter, $this->intAttrDelimiter, $attributes );
307
        $content = $this->nl.$this->_createElement( 'extref', $attributes, null );
308
        $attributes = null;
309
      }
310
    }
311
    elseif(( 'xcal' == $this->format) && ( 'attach' == $label ) && $attachInlineBinary ) {
312
      $content = $this->nl.$this->_createElement( 'b64bin', $attachfmttype, $content ); // max one attribute
313
    }
314
    $output .= $attributes;
315
    if( !$content && ( '0' != $content )) {
316
      switch( $this->format ) {
317
        case 'xcal':
318
          $output .= ' /';
319
          $output .= $this->elementStart2.$this->nl;
320
          return $output;
321
          break;
322
        default:
323
          $output .= $this->elementStart2.$this->valueInit;
324
          return iCalUtilityFunctions::_size75( $output, $this->nl );
325
          break;
326
      }
327
    }
328
    $output .= $this->elementStart2;
329
    $output .= $this->valueInit.$content;
330
    switch( $this->format ) {
331
      case 'xcal':
332
        return $output.$this->elementEnd1.$label.$this->elementEnd2;
333
        break;
334
      default:
335
        return iCalUtilityFunctions::_size75( $output, $this->nl );
336
        break;
337
    }
338
  }
339
/**
340
 * creates formatted output for calendar component property parameters
341
 *
342
 * @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
343
 * @since 2.21.11 - 2015-03-31
344
 * @param array $params  optional
345
 * @param array $ctrKeys optional
346
 * @uses iCalBase::$intAttrDelimiter
347
 * @uses vcalendar::getConfig()
348
 * @uses calendarComponent::getConfig()
349
 * @access protected
350
 * @return string
351
 */
352
  protected function _createParams( $params=array(), $ctrKeys=array() ) {
353
    if( !is_array( $params ) || empty( $params ))
354
      $params = array();
355
    $attrLANG = $attr1 = $attr2 = $lang = null;
356
    $CNattrKey   = ( in_array( 'CN',       $ctrKeys )) ? TRUE : FALSE ;
357
    $LANGattrKey = ( in_array( 'LANGUAGE', $ctrKeys )) ? TRUE : FALSE ;
358
    $CNattrExist = $LANGattrExist = FALSE;
359
    $xparams = array();
360
    $params  = array_change_key_case( $params, CASE_UPPER );
361
    foreach( $params as $paramKey => $paramValue ) {
362
      if(( FALSE !== strpos( $paramValue, ':' )) ||
363
         ( FALSE !== strpos( $paramValue, ';' )) ||
364
         ( FALSE !== strpos( $paramValue, ',' )))
365
        $paramValue = '"'.$paramValue.'"';
366
      if( ctype_digit( (string) $paramKey )) {
367
        $xparams[]          = $paramValue;
368
        continue;
369
      }
370
      if( !in_array( $paramKey, array( 'ALTREP', 'CN', 'DIR', 'ENCODING', 'FMTTYPE', 'LANGUAGE', 'RANGE', 'RELTYPE', 'SENT-BY', 'TZID', 'VALUE' )))
371
        $xparams[$paramKey] = $paramValue;
372
      else
373
        $params[$paramKey]  = $paramValue;
374
    }
375
    ksort( $xparams, SORT_STRING );
376
    foreach( $xparams as $paramKey => $paramValue ) {
377
      if( ctype_digit( (string) $paramKey ))
378
        $attr2             .= $this->intAttrDelimiter.$paramValue;
379
      else
380
        $attr2             .= $this->intAttrDelimiter."$paramKey=$paramValue";
381
    }
382
    if( isset( $params['FMTTYPE'] )  && !in_array( 'FMTTYPE', $ctrKeys )) {
383
      $attr1               .= $this->intAttrDelimiter.'FMTTYPE='.$params['FMTTYPE'].$attr2;
384
      $attr2                = null;
385
    }
386
    if( isset( $params['ENCODING'] ) && !in_array( 'ENCODING',   $ctrKeys )) {
387
      if( !empty( $attr2 )) {
388
        $attr1             .= $attr2;
389
        $attr2              = null;
390
      }
391
      $attr1               .= $this->intAttrDelimiter.'ENCODING='.$params['ENCODING'];
392
    }
393
    if( isset( $params['VALUE'] )    && !in_array( 'VALUE',   $ctrKeys ))
394
      $attr1               .= $this->intAttrDelimiter.'VALUE='.$params['VALUE'];
395
    if( isset( $params['TZID'] )     && !in_array( 'TZID',    $ctrKeys )) {
396
      $attr1               .= $this->intAttrDelimiter.'TZID='.$params['TZID'];
397
    }
398
    if( isset( $params['RANGE'] )    && !in_array( 'RANGE',   $ctrKeys ))
399
      $attr1               .= $this->intAttrDelimiter.'RANGE='.$params['RANGE'];
400
    if( isset( $params['RELTYPE'] )  && !in_array( 'RELTYPE', $ctrKeys ))
401
      $attr1               .= $this->intAttrDelimiter.'RELTYPE='.$params['RELTYPE'];
402
    if( isset( $params['CN'] )       && $CNattrKey ) {
403
      $attr1                = $this->intAttrDelimiter.'CN='.$params['CN'];
404
      $CNattrExist          = TRUE;
405
    }
406
    if( isset( $params['DIR'] )      && in_array( 'DIR',      $ctrKeys )) {
407
      $delim = ( FALSE !== strpos( $params['DIR'], '"' )) ? '' : '"';
408
      $attr1               .= $this->intAttrDelimiter.'DIR='.$delim.$params['DIR'].$delim;
409
    }
410
    if( isset( $params['SENT-BY'] )  && in_array( 'SENT-BY',  $ctrKeys ))
411
      $attr1               .= $this->intAttrDelimiter.'SENT-BY='.$params['SENT-BY'];
412
    if( isset( $params['ALTREP'] )   && in_array( 'ALTREP',   $ctrKeys )) {
413
      $delim = ( FALSE !== strpos( $params['ALTREP'], '"' )) ? '' : '"';
414
      $attr1               .= $this->intAttrDelimiter.'ALTREP='.$delim.$params['ALTREP'].$delim;
415
    }
416
    if( isset( $params['LANGUAGE'] ) && $LANGattrKey ) {
417
      $attrLANG            .= $this->intAttrDelimiter.'LANGUAGE='.$params['LANGUAGE'];
418
      $LANGattrExist        = TRUE;
419
    }
420
    if( !$LANGattrExist ) {
421
      $lang = $this->getConfig( 'language' );
422
      if(( $CNattrExist || $LANGattrKey ) && $lang )
423
        $attrLANG .= $this->intAttrDelimiter.'LANGUAGE='.$lang;
424
    }
425
    return $attr1.$attrLANG.$attr2;
426
  }
427
}