Subversion Repositories regexpline_backup

[/] [stable/] [2.3/] [datatypes/] [hmregexpline/] [hmregexplinetype.php] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xrow
<?php
2
 
3
/*
4
    Regular Expression datatype for eZ publish 3.x
5
    Copyright (C) 2005-2006  Hans Melis
6
 
7
    This program is free software; you can redistribute it and/or modify
8
    it under the terms of the GNU General Public License as published by
9
    the Free Software Foundation; either version 2 of the License, or
10
    (at your option) any later version.
11
 
12
    This program is distributed in the hope that it will be useful,
13
    but WITHOUT ANY WARRANTY; without even the implied warranty of
14
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
    GNU General Public License for more details.
16
*/
17
 
18
/*!
19
  \class   hmregexplinetype hmregexplinetype.php
20
  \ingroup eZDatatype
21
  \brief   Handles the datatype regexpline
22
  \version 2.0
23
  \date    Wednesday 01 March 2006 17:19:23 pm
24
  \author  Hans Melis
25
 
26
  By using regexpline you can ... do stuff :)
27
 
28
*/
29
 
30
include_once( 'kernel/classes/ezdatatype.php' );
31
 
32
include_once( 'lib/ezutils/classes/ezini.php' );
33
 
34
include_once( 'kernel/common/i18n.php' );
35
 
36
define( 'EZ_DATATYPESTRING_REGEXPLINE', 'hmregexpline' );
37
 
38
class hmregexplinetype extends eZDataType
39
{
40
    /*!
41
      Constructor
42
    */
43
    function hmregexplinetype()
44
    {
45
        $this->eZDataType( EZ_DATATYPESTRING_REGEXPLINE,
46
                           ezi18n( 'extension/regexpline/datatype', 'Regular Expression Text', 'Datatype name' ),
47
                           array( 'serialize_supported' => true ) );
48
 
49
        $this->KeepTags = null;
50
    }
51
 
52
    /*!
53
    Validates all variables given on content class level
54
     \return EZ_INPUT_VALIDATOR_STATE_ACCEPTED or EZ_INPUT_VALIDATOR_STATE_INVALID if
55
             the values are accepted or not
56
    */
57
    function validateClassAttributeHTTPInput( &$http, $base, &$classAttribute )
58
    {
59
        $regexpName = $base . "_hmregexpline_regexp_" . $classAttribute->attribute( 'id' );
60
        $presetName = $base . "_hmregexpline_preset_" . $classAttribute->attribute( 'id' );
61
 
62
        $regexp = $preset = array();
63
 
64
        $this->clearClassErrorMessages( $classAttribute );
65
 
66
        if( $http->hasPostVariable( $regexpName ) )
67
        {
68
            $regexp = $http->postVariable( $regexpName );
69
        }
70
 
71
        if( $http->hasPostVariable( $presetName ) )
72
        {
73
            $preset = $http->postVariable( $presetName );
74
        }
75
 
76
        $content = array( 'regexp' => $regexp,
77
                          'preset' => $preset );
78
        $regexp = $this->getRegularExpression( $content );
79
 
80
        if( count( $regexp ) == 0 )
81
        {
82
            $this->addClassErrorMessage( $classAttribute,
83
                ezi18n( 'extension/regexpline/datatype', 'You need at least one regular expression or selected preset' ) );        
84
                return EZ_INPUT_VALIDATOR_STATE_INVALID;
85
        }
86
 
87
        foreach( $regexp as $expr )
88
        {
89
            $check = @preg_match( $expr, 'Dummy string' );
90
 
91
            if( $check === false )
92
            {
93
                $this->addClassErrorMessage( $classAttribute,
94
                    ezi18n( 'extension/regexpline/datatype', 'The regular expression "%1" is invalid', null, array( $expr ) ) );
95
                return EZ_INPUT_VALIDATOR_STATE_INVALID;
96
            }
97
        }
98
 
99
        return EZ_INPUT_VALIDATOR_STATE_ACCEPTED;
100
    }
101
 
102
    /*!
103
     Fetches all variables inputed on content class level
104
     \return true if fetching of class attributes are successfull, false if not
105
    */
106
    function fetchClassAttributeHTTPInput( &$http, $base, &$classAttribute )
107
    {
108
        $regexpName = $base . "_hmregexpline_regexp_" . $classAttribute->attribute( 'id' );
109
        $errorsName = $base . "_hmregexpline_errmsg_" . $classAttribute->attribute( 'id' );
110
        $helpName = $base . "_hmregexpline_helptext_" . $classAttribute->attribute( 'id' );
111
        $patternName = $base . "_hmregexpline_namepattern_" . $classAttribute->attribute( 'id' );
112
        $presetName = $base . "_hmregexpline_preset_" . $classAttribute->attribute( 'id' );
113
        $displayName = $base . "_hmregexpline_display_"  . $classAttribute->attribute( 'id' );
114
        $negateName = $base . "_hmregexpline_negate_" . $classAttribute->attribute( 'id' );
115
 
116
        $content = $classAttribute->content();
117
 
118
        if( $http->hasPostVariable( $regexpName ) )
119
        {
120
            $content['regexp'] = $http->postVariable( $regexpName );
121
        }
122
 
123
        if( $http->hasPostVariable( $errorsName ) )
124
        {
125
            $content['error_messages'] = $http->postVariable( $errorsName );
126
        }
127
 
128
        if( $http->hasPostVariable( $presetName ) )
129
        {
130
            $content['preset'] = $http->postVariable( $presetName );
131
        }
132
        else if( $http->hasPostVariable( 'ContentClassHasInput' ) )
133
        {
134
            $content['preset'] = array();
135
        }
136
 
137
        if( $http->hasPostVariable( $helpName ) )
138
        {
139
            $content['help_text'] = $http->postVariable( $helpName );
140
        }
141
 
142
        if( $http->hasPostVariable( $patternName ) )
143
        {
144
            $content['naming_pattern'] = $http->postVariable( $patternName );
145
        }
146
        else if( $http->hasPostVariable( 'ContentClassHasInput' ) )
147
        {
148
            $content['naming_pattern'] = '';
149
        }
150
 
151
        if( $http->hasPostVariable( $displayName ) )
152
        {
153
            $content['display_type'] = $http->postVariable( $displayName );
154
        }
155
        else if( $http->hasPostVariable( 'ContentClassHasInput' ) )
156
        {
157
            $content['display_type'] = 'line'; // default
158
        }
159
 
160
        if( $http->hasPostVariable( $negateName ) )
161
        {
162
            $negates = $http->postVariable( $negateName );
163
            $content['negates'] = array();
164
 
165
            foreach( $negates as $key => $value )
166
            {
167
                $content['negates'][$key] = true;
168
            }
169
        }
170
        else if( $http->hasPostVariable( 'ContentClassHasInput' ) )
171
        {
172
            $content['negates'] = array();
173
        }
174
 
175
        $regexp = $this->getRegularExpression( $content );
176
        $subPatternCount = 0;
177
        $subPatterns = array();
178
 
179
        foreach( $regexp as $expr )
180
        {
181
            $subPatternCount += @preg_match_all( "/\((?!\?\:)(.*)\)/U", $expr, $matches, PREG_PATTERN_ORDER );
182
            $subPatterns = array_merge( $subPatterns, $matches[1] );
183
        }
184
 
185
        $content['subpattern_count'] = $subPatternCount == false ? 0 : $subPatternCount;
186
        $content['subpatterns'] = $subPatterns;
187
 
188
        $classAttribute->setContent( $content );
189
        $classAttribute->store();
190
 
191
        return true;
192
    }
193
 
194
    function storeClassAttribute( &$classAttribute, $version )
195
    {
196
        $content = $classAttribute->content();
197
 
198
        $classAttribute->setAttribute( 'data_text5', serialize( $content ) );
199
    }
200
 
201
    function &classAttributeContent( &$classAttribute )
202
    {
203
        $content = unserialize( $classAttribute->attribute( 'data_text5' ) );
204
 
205
        if( !is_array( $content ) )
206
        {
207
            $content = array( 'regexp' => array(),
208
                              'error_messages' => array(),
209
                              'negates' => array(),
210
                              'preset' => array(),
211
                              'help_text' => '',
212
                              'subpattern_count' => 0,
213
                              'subpatterns' => array(),
214
                              'naming_pattern' => '',
215
                              'display_type' => 'line' );
216
        }
217
 
218
        if( isset( $content['pattern_selection'] ) )
219
        {
220
            $this->migratePatternSelection( $content );
221
        }
222
 
223
        if( !is_array( $content['regexp'] ) )
224
        {
225
            $content['regexp'] = array( $content['regexp'] );
226
        }
227
 
228
        if( !is_array( $content['preset'] ) )
229
        {
230
            $tmpPreset = array();
231
 
232
            if( !empty( $content['preset'] ) )
233
            {
234
                $tmpPreset[] = $content['preset'];
235
            }
236
 
237
            $content['preset'] = $tmpPreset;
238
        }
239
 
240
        if( !isset( $content['display_type'] ) )
241
        {
242
            $content['display_type'] = 'line';
243
        }
244
 
245
        if( !isset( $content['error_messages'] ) )
246
        {
247
            $content['error_messages'] = array();
248
        }
249
 
250
        if( !isset( $content['negates'] ) )
251
        {
252
            $content['negates'] = array();
253
        }
254
 
255
        return $content;
256
    }
257
 
258
    /*!
259
     Validates input on content object level
260
     \return EZ_INPUT_VALIDATOR_STATE_ACCEPTED or EZ_INPUT_VALIDATOR_STATE_INVALID if
261
             the values are accepted or not
262
    */
263
    function validateObjectAttributeHTTPInput( &$http, $base, &$contentObjectAttribute )
264
    {
265
        $status = $this->validateAttributeHTTPInput( $http, $base, $contentObjectAttribute, false );
266
 
267
        return $status;
268
    }
269
 
270
    /*!
271
     Fetches all variables from the object
272
     \return true if fetching of class attributes are successfull, false if not
273
    */
274
    function fetchObjectAttributeHTTPInput( &$http, $base, &$contentObjectAttribute )
275
    {
276
        $textName = $base . "_hmregexpline_data_text_" . $contentObjectAttribute->attribute( 'id' );
277
 
278
        if( $http->hasPostVariable( $textName ) )
279
        {
280
            $text = $http->postVariable( $textName );
281
            $contentObjectAttribute->setContent( $text );
282
            $contentObjectAttribute->storeData();
283
            return true;
284
        }
285
        return false;
286
    }
287
 
288
    function storeObjectAttribute( &$contentObjectAttribute )
289
    {
290
        $text = $contentObjectAttribute->content();
291
 
292
        $contentObjectAttribute->setAttribute( 'data_text', $text );
293
    }
294
 
295
    /*!
296
     Returns the content.
297
    */
298
    function &objectAttributeContent( &$contentObjectAttribute )
299
    {
300
        $text = $contentObjectAttribute->attribute( 'data_text' );
301
 
302
        return $text;
303
    }
304
 
305
    function hasObjectAttributeContent( &$contentObjectAttribute )
306
    {
307
        $text = $contentObjectAttribute->attribute( 'data_text' );
308
        $result = !empty( $text );
309
 
310
        return $result;
311
    }
312
 
313
    function validateAttributeHTTPInput( &$http, $base, &$objectAttribute, $isInformationCollector = false )
314
    {
315
        $textName = $base . "_hmregexpline_data_text_" . $objectAttribute->attribute( 'id' );
316
        $classAttribute =& $objectAttribute->contentClassAttribute();
317
 
318
        $required = false;
319
        $must_validate = ( $isInformationCollector == $classAttribute->attribute( 'is_information_collector' ) );
320
 
321
        if( method_exists( $objectAttribute, 'validateIsRequired' ) )
322
        {
323
            $required = $objectAttribute->validateIsRequired();
324
        }
325
        else
326
        {
327
            $required = ( $classAttribute->attribute( 'is_required' ) == 1 );
328
        }
329
 
330
        if( $http->hasPostVariable( $textName ) )
331
        {
332
            $text = $http->postVariable( $textName );
333
            $classContent = $classAttribute->content();
334
 
335
            if( empty( $text ) and ( $required === true && $must_validate === true ) )
336
            {
337
                $objectAttribute->setValidationError( ezi18n( 'extension/regexpline/datatype', 'This is a required field.' ) );
338
                return EZ_INPUT_VALIDATOR_STATE_INVALID;
339
            }
340
 
341
            if( !empty( $text ) )
342
            {
343
                $regexp = $this->getRegularExpression( $classContent );
344
                $text = $this->stripTags( $objectAttribute, $text );
345
 
346
                foreach( $regexp as $index => $expr )
347
                {
348
                    $doNegate = isset( $classContent['negates'][$index] );
349
                    $res = @preg_match( $expr, $text );
350
 
351
                    if( $doNegate === false )
352
                    {
353
                        $condition = ( $res === 0 );
354
                    }
355
                    else
356
                    {
357
                        $condition = ( $res === 1 );
358
                    }
359
 
360
                    if( $condition )
361
                    {
362
                        // No match
363
                        $msg = $this->getErrorMessage( $classContent, $index );
364
 
365
                        if( $msg === null )
366
                        {
367
                            $msg = ezi18n( 'extension/regexpline/datatype', 'Your input did not meet the requirements.' );
368
                        }
369
 
370
                        $objectAttribute->setValidationError( $msg );
371
                        return EZ_INPUT_VALIDATOR_STATE_INVALID;
372
                    }
373
                }
374
            }
375
        }
376
        else
377
        {
378
            if( $required === true && $must_validate === true )
379
            {
380
                $objectAttribute->setValidationError( ezi18n( 'extension/regexpline/datatype', 'This is a required field.' ) );
381
                return EZ_INPUT_VALIDATOR_STATE_INVALID;
382
            }
383
        }
384
 
385
        return EZ_INPUT_VALIDATOR_STATE_ACCEPTED;
386
    }
387
 
388
    function validateCollectionAttributeHTTPInput( &$http, $base, &$objectAttribute )
389
    {
390
        $status = $this->validateAttributeHTTPInput( $http, $base, $objectAttribute, true );
391
 
392
        return $status;
393
    }
394
 
395
    function fetchCollectionAttributeHTTPInput( &$collection, &$collectionAttribute, &$http, $base, &$contentObjectAttribute )
396
    {
397
        $textName = $base . "_hmregexpline_data_text_" . $contentObjectAttribute->attribute( 'id' );
398
 
399
        if( $http->hasPostVariable( $textName ) )
400
        {
401
            $text = $http->postVariable( $textName );
402
            $collectionAttribute->setAttribute( 'data_text', $text );
403
            return true;
404
        }
405
 
406
        return false;
407
    }
408
 
409
    /*!
410
     Returns the meta data used for storing search indeces.
411
    */
412
    function metaData( $contentObjectAttribute )
413
    {
414
        $data = $contentObjectAttribute->attribute( 'data_text' );
415
 
416
        $data = $this->stripTags( $contentObjectAttribute, $data );
417
 
418
        return $data;
419
    }
420
 
421
    /*!
422
     Returns the value as it will be shown if this attribute is used in the object name pattern.
423
    */
424
    function title( &$contentObjectAttribute )
425
    {
426
        $classAttribute =& $contentObjectAttribute->contentClassAttribute();
427
        $classContent = $classAttribute->content();
428
        $content = $contentObjectAttribute->content();
429
        $title = "";
430
 
431
        // Exit if the input is empty
432
        if( $content == '' )
433
        {
434
            return $content;
435
        }
436
        else
437
        {
438
            $content = $this->stripTags( $contentObjectAttribute, $content );
439
        }
440
 
441
        if( isset( $classContent['pattern_selection'] ) )
442
        {
443
            $this->migratePatternSelection( $classContent );
444
        }
445
 
446
        $regexp = $this->getRegularExpression( $classContent );
447
        $res = 0;
448
        $matchArray = array( $content );
449
 
450
        foreach( $regexp as $index => $expr )
451
        {
452
            $res += @preg_match( $expr, $content, $matches );
453
            unset( $matches[0] ); // We don't need this one
454
            $matchArray = array_merge( $matchArray, $matches );
455
        }
456
 
457
        // Only replace if there's at least a match
458
        if( (count( $matchArray ) - 1) == $classContent['subpattern_count'] )
459
        {
460
            if( $classContent['naming_pattern'] != '' )
461
            {
462
                $title = preg_replace( "/<([0-9]+)>/e", "\$matchArray[\\1]", $classContent['naming_pattern'] );
463
            }
464
            else
465
            {
466
                $title = $matchArray[0];
467
            }
468
        }
469
 
470
        return $title;
471
    }
472
 
473
    /*!
474
     \return true if the datatype can be indexed
475
    */
476
    function isIndexable()
477
    {
478
        return true;
479
    }
480
 
481
    function isInformationCollector()
482
    {
483
        return true;
484
    }
485
 
486
    function &sortKey( &$contentObjectAttribute )
487
    {
488
        $text = $contentObjectAttribute->content();
489
 
490
        return $text;
491
    }
492
 
493
    function &sortKeyType()
494
    {
495
        return 'string';
496
    }
497
 
498
    function serializeContentClassAttribute( &$classAttribute, &$attributeNode, &$attributeParametersNode )
499
    {
500
        $serializedContent = $classAttribute->attribute( 'data_text5' );
501
 
502
        $attributeParametersNode->appendChild( eZDOMDocument::createElementCDATANode( 'content', $serializedContent ) );
503
    }
504
 
505
    function unserializeContentClassAttribute( &$classAttribute, &$attributeNode, &$attributeParametersNode )
506
    {
507
        $serializedContent = $attributeParametersNode->elementTextContentByName( 'content' );
508
 
509
        $classAttribute->setAttribute( 'data_text5', $serializedContent );
510
    }
511
 
512
 
513
    function getRegularExpression( &$classContent )
514
    {
515
        $regexp = $classContent['regexp'];
516
 
517
        if( !is_array( $classContent['preset'] ) )
518
        {
519
            $tmpPreset = array();
520
 
521
            if( !empty( $classContent['preset'] ) )
522
            {
523
                $tmpPreset[] = $classContent['preset'];
524
            }
525
 
526
            $classContent['preset'] = $tmpPreset;
527
        }
528
 
529
        if( count( $classContent['preset'] ) > 0 )
530
        {
531
            $tmpRegexp = array();
532
            $ini =& eZINI::instance( 'regexpline.ini' );
533
            $presets = $ini->variable( 'GeneralSettings', 'RegularExpressions' );
534
 
535
            foreach( $classContent['preset'] as $preset )
536
            {
537
                if( isset( $presets[$preset] ) )
538
                {
539
                    $tmpRegexp[$preset] = $presets[$preset];
540
                }
541
            }
542
 
543
            $regexp = $tmpRegexp;
544
        }
545
 
546
        if( !is_array( $regexp ) )
547
        {
548
            $regexp = array( $regexp );
549
        }
550
 
551
        return $regexp;
552
    }
553
 
554
    function getErrorMessage( &$classContent, $index )
555
    {
556
        $msg = null;
557
 
558
        if( isset( $classContent['error_messages'] ) && is_array( $classContent['error_messages'] ) )
559
        {
560
            if( isset( $classContent['error_messages'][$index] ) )
561
            {
562
                $msg = $classContent['error_messages'][$index];
563
            }
564
        }
565
 
566
        // Presets override
567
        if( count( $classContent['preset'] ) > 0 )
568
        {
569
            $ini =& eZINI::instance( 'regexpline.ini' );
570
            $presets = $ini->variable( 'GeneralSettings', 'RegularExpressions' );
571
            $messages = $ini->variable( 'GeneralSettings', 'ErrorMessages' );
572
            $msgIndex = $index;
573
 
574
            if( isset( $classContent['negates'][$index] ) )
575
            {
576
                $msgIndex .= '_negate';
577
            }
578
 
579
            if( isset( $presets[$index] ) && isset( $messages[$msgIndex] ) )
580
            {
581
                $msg = $messages[$msgIndex];
582
            }
583
        }
584
 
585
        return $msg;
586
    }
587
 
588
    function migratePatternSelection( &$classContent )
589
    {
590
        // Migrate the old pattern_selection to the newer naming_pattern
591
        $content['naming_pattern'] = '';
592
 
593
        foreach( $content['pattern_selection'] as $pattern )
594
        {
595
            $content['naming_pattern'] .= "<$pattern>";
596
        }
597
 
598
        unset( $content['pattern_selection'] );
599
    }
600
 
601
    function doStripTags( &$objectAttribute )
602
    {
603
        if( $this->KeepTags === null )
604
        {
605
            $regIni =& eZINI::instance( 'regexpline.ini' );
606
 
607
            if( $regIni->hasVariable( 'GeneralSettings', 'KeepTags' ) )
608
            {
609
                include_once( 'kernel/classes/ezcontentobjecttreenode.php' );
610
                // Don't ask why they've put that function in there :-s
611
 
612
                $keepTags = $regIni->variable( 'GeneralSettings', 'KeepTags' );
613
                $keepTagsResult = array();
614
 
615
                foreach( $keepTags as $identifier )
616
                {
617
                    $keepTagsResult[] = eZContentObjectTreeNode::classAttributeIDByIdentifier( $identifier );
618
                }
619
 
620
                $this->KeepTags = $keepTagsResult;
621
            }
622
            else
623
            {
624
                return true;
625
            }
626
        }
627
 
628
        $shouldStrip = true;
629
        $classAttributeID =& $objectAttribute->attribute( 'contentclassattribute_id' );
630
 
631
        if( is_array( $this->KeepTags ) && in_array( $classAttributeID, $this->KeepTags ) )
632
        {
633
            $shouldStrip = false;
634
        }
635
 
636
        return $shouldStrip;
637
    }
638
 
639
    function stripTags( &$objectAttribute, $content )
640
    {
641
        if( $this->doStripTags( $objectAttribute ) === true )
642
        {
643
            $content = strip_tags( $content );
644
        }
645
 
646
        return $content;
647
    }
648
 
649
    function addClassErrorMessage( &$classAttribute, $message )
650
    {
651
        $content =& $classAttribute->content();
652
 
653
        $content['class_validation_messages'][] = $message;
654
 
655
        $classAttribute->setContent( $content );
656
        $classAttribute->store();
657
    }
658
 
659
    function clearClassErrorMessages( &$classAttribute )
660
    {
661
        $content =& $classAttribute->content();
662
 
663
        $content['class_validation_messages'] = array();
664
 
665
        $classAttribute->setContent( $content );
666
        $classAttribute->store();
667
    }
668
 
669
    var $KeepTags = null;
670
}
671
 
672
eZDataType::register( EZ_DATATYPESTRING_REGEXPLINE, "hmregexplinetype" );
673
 
674
?>