Subversion Repositories regexpline_backup

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