- Fixed several bug in class/classattribute translations.
[tinyz:tinyz.git] / kernel / class / edit.php
1 <?php
2 //
3 // Created on: <16-Apr-2002 11:00:12 amos>
4 //
5 // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
6 // SOFTWARE NAME: eZ publish
7 // SOFTWARE RELEASE: 3.8.x
8 // COPYRIGHT NOTICE: Copyright (C) 1999-2006 eZ systems AS
9 // SOFTWARE LICENSE: GNU General Public License v2.0
10 // NOTICE: >
11 //   This program is free software; you can redistribute it and/or
12 //   modify it under the terms of version 2.0  of the GNU General
13 //   Public License as published by the Free Software Foundation.
14 //
15 //   This program is distributed in the hope that it will be useful,
16 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
17 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 //   GNU General Public License for more details.
19 //
20 //   You should have received a copy of version 2.0 of the GNU General
21 //   Public License along with this program; if not, write to the Free
22 //   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
23 //   MA 02110-1301, USA.
24 //
25 //
26 // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
27 //
28
29 include_once( 'kernel/classes/ezcontentclass.php' );
30 include_once( 'kernel/classes/ezcontentclassattribute.php' );
31 include_once( 'kernel/classes/ezcontentclassclassgroup.php' );
32 include_once( 'lib/ezutils/classes/ezhttptool.php' );
33 include_once( 'lib/ezutils/classes/ezhttppersistence.php' );
34
35
36 $Module =& $Params['Module'];
37 $ClassID = $Params['ClassID'];
38 $GroupID = $Params['GroupID'];
39 $GroupName = $Params['GroupName'];
40 $EditLanguage = $Params['Language'];
41 $FromLanguage = false;
42 $ClassVersion = null;
43
44 switch ( $Params['FunctionName'] )
45 {
46     case 'edit':
47     {
48     } break;
49     default:
50     {
51         eZDebug::writeError( 'Undefined function: ' . $params['Function'] );
52         $Module->setExitStatus( EZ_MODULE_STATUS_FAILED );
53         return;
54     };
55 }
56
57 $http =& eZHttpTool::instance();
58 if ( $http->hasPostVariable( 'CancelConflictButton' ) )
59 {
60     $Module->redirectToView( 'grouplist' );
61 }
62
63 if ( $http->hasPostVariable( 'EditLanguage' ) )
64 {
65     $EditLanguage = $http->postVariable( 'EditLanguage' );
66 }
67
68 if ( is_numeric( $ClassID ) )
69 {
70     $class = eZContentClass::fetch( $ClassID, true, EZ_CLASS_VERSION_STATUS_TEMPORARY );
71
72     // If temporary version does not exist fetch the current and add temperory class to corresponding group
73     if ( !is_object( $class ) or $class->attribute( 'id' ) == null )
74     {
75         $class = eZContentClass::fetch( $ClassID, true, EZ_CLASS_VERSION_STATUS_DEFINED );
76         if( is_null( $class ) ) // Class does not exist
77         {
78             return $Module->handleError( EZ_ERROR_KERNEL_NOT_AVAILABLE, 'kernel' );
79         }
80         $classGroups= eZContentClassClassGroup::fetchGroupList( $ClassID, EZ_CLASS_VERSION_STATUS_DEFINED );
81         foreach ( $classGroups as $classGroup )
82         {
83             $groupID = $classGroup->attribute( 'group_id' );
84             $groupName = $classGroup->attribute( 'group_name' );
85             $ingroup = eZContentClassClassGroup::create( $ClassID, EZ_CLASS_VERSION_STATUS_TEMPORARY, $groupID, $groupName );
86             $ingroup->store();
87         }
88     }
89     else
90     {
91         include_once( 'lib/ezlocale/classes/ezdatetime.php' );
92         $user =& eZUser::currentUser();
93         $contentIni =& eZIni::instance( 'content.ini' );
94         $timeOut = $contentIni->variable( 'ClassSettings', 'DraftTimeout' );
95
96         if ( $class->attribute( 'modifier_id' ) != $user->attribute( 'contentobject_id' ) &&
97              $class->attribute( 'modified' ) + $timeOut > time() )
98         {
99             include_once( 'kernel/common/template.php' );
100             $tpl =& templateInit();
101
102             $res =& eZTemplateDesignResource::instance();
103             $res->setKeys( array( array( 'class', $class->attribute( 'id' ) ) ) ); // Class ID
104             $tpl->setVariable( 'class', $class );
105             $tpl->setVariable( 'lock_timeout', $timeOut );
106
107             $Result = array();
108             $Result['content'] =& $tpl->fetch( 'design:class/edit_denied.tpl' );
109             $Result['path'] = array( array( 'url' => '/class/grouplist/',
110                                             'text' => ezi18n( 'kernel/class', 'Class list' ) ) );
111             return $Result;
112         }
113     }
114 }
115 else
116 {
117     include_once( 'kernel/classes/datatypes/ezuser/ezuser.php' );
118
119     if ( !$EditLanguage )
120         $EditLanguage = eZContentClass::defaultLanguage();
121
122     $user =& eZUser::currentUser();
123     $user_id = $user->attribute( 'contentobject_id' );
124     $class = eZContentClass::create( $user_id, array(), $EditLanguage );
125     $class->setName( ezi18n( 'kernel/class/edit', 'New Class' ), $EditLanguage );
126     $class->store();
127     $editLanguageID = eZContentLanguage::idByLocale( $EditLanguage );
128     $class->setAlwaysAvailableLanguageID( $editLanguageID );
129     $ClassID = $class->attribute( 'id' );
130     $ClassVersion = $class->attribute( 'version' );
131     $ingroup = eZContentClassClassGroup::create( $ClassID, $ClassVersion, $GroupID, $GroupName );
132     $ingroup->store();
133     $Module->redirectTo( $Module->functionURI( 'edit' ) . '/' . $ClassID . '/(language)/' . $EditLanguage );
134     return;
135 }
136
137
138 $contentClassHasInput = true;
139 if ( $http->hasPostVariable( 'ContentClassHasInput' ) )
140     $contentClassHasInput = $http->postVariable( 'ContentClassHasInput' );
141
142 // Find out the group where class is created or edited from.
143 if ( $http->hasSessionVariable( 'FromGroupID' ) )
144 {
145     $fromGroupID = $http->sessionVariable( 'FromGroupID' );
146 }
147 else
148 {
149     $fromGroupID = false;
150 }
151 $ClassID = $class->attribute( 'id' );
152 $ClassVersion = $class->attribute( 'version' );
153
154 $validation = array( 'processed' => false,
155                      'groups' => array(),
156                      'attributes' => array(),
157                      'class_errors' => array() );
158 $unvalidatedAttributes = array();
159
160 if ( $http->hasPostVariable( 'DiscardButton' ) )
161 {
162     eZSessionDestroy( $http->sessionVariable( 'CanStoreTicket' ) );
163     $http->removeSessionVariable( 'CanStoreTicket' );
164     $class->setVersion( EZ_CLASS_VERSION_STATUS_TEMPORARY );
165     $class->remove( true, EZ_CLASS_VERSION_STATUS_TEMPORARY );
166     eZContentClassClassGroup::removeClassMembers( $ClassID, EZ_CLASS_VERSION_STATUS_TEMPORARY );
167     if ( $fromGroupID === false )
168     {
169         $Module->redirectToView( 'grouplist' );
170     }
171     else
172     {
173         $Module->redirectTo( $Module->functionURI( 'classlist' ) . '/' . $fromGroupID . '/' );
174     }
175     return;
176 }
177 if ( $http->hasPostVariable( 'AddGroupButton' ) && $http->hasPostVariable( 'ContentClass_group' ) )
178 {
179     include_once( "kernel/class/ezclassfunctions.php" );
180     eZClassFunctions::addGroup( $ClassID, $ClassVersion, $http->postVariable( 'ContentClass_group' ) );
181 }
182 if ( $http->hasPostVariable( 'RemoveGroupButton' ) && $http->hasPostVariable( 'group_id_checked' ) )
183 {
184     include_once( "kernel/class/ezclassfunctions.php" );
185     if ( !eZClassFunctions::removeGroup( $ClassID, $ClassVersion, $http->postVariable( 'group_id_checked' ) ) )
186     {
187         $validation['groups'][] = array( 'text' => ezi18n( 'kernel/class', 'You have to have at least one group that the class belongs to!' ) );
188         $validation['processed'] = true;
189     }
190 }
191
192 // Fetch attributes and definitions
193 $attributes =& $class->fetchAttributes();
194
195 if ( $http->hasPostVariable( 'SelectLanguageButton' ) && $http->hasPostVariable( 'EditLanguage' ) )
196 {
197     $EditLanguage = $http->postVariable( 'EditLanguage' );
198
199     $FromLanguage = 'None';
200     if ( $http->hasPostVariable( 'FromLanguage' ) )
201         $FromLanguage = $http->postVariable( 'FromLanguage' );
202
203     foreach ( array_keys( $attributes ) as $key )
204     {
205         $name = '';
206         if ( $FromLanguage != 'None' )
207         {
208             $name = $attributes[$key]->name( $FromLanguage );
209         }
210         $attributes[$key]->setName( $name, $EditLanguage );
211     }
212
213     $name = '';
214     if ( $FromLanguage != 'None' )
215     {
216         $name = $class->name( $FromLanguage );
217     }
218
219     $class->setName( $name, $EditLanguage );
220 }
221
222 // No language was specified in the URL, we need to figure out
223 // the language to use.
224 if ( !$EditLanguage )
225 {
226     // Check number of languages
227     include_once( 'kernel/classes/ezcontentlanguage.php' );
228     $languages = eZContentLanguage::fetchList();
229     // If there is only one language we choose it for the user.
230     if ( count( $languages ) == 1 )
231     {
232         $EditLanguage = array_shift( $languages );
233     }
234     else
235     {
236         $canCreateLanguages = $class->attribute( 'can_create_languages' );
237         if ( count( $canCreateLanguages ) == 0)
238         {
239             $EditLanguage = $class->attribute( 'top_priority_language' );
240         }
241         else
242         {
243             include_once( 'kernel/common/template.php' );
244
245             $tpl =& templateInit();
246
247             $res =& eZTemplateDesignResource::instance();
248             $res->setKeys( array( array( 'class', $class->attribute( 'id' ) ) ) ); // Class ID
249
250             $tpl->setVariable( 'module', $Module );
251             $tpl->setVariable( 'class', $class );
252
253             $Result = array();
254             $Result['content'] =& $tpl->fetch( 'design:class/select_language.tpl' );
255             $Result['path'] = array( array( 'url' => '/class/edit/',
256                                             'text' => ezi18n( 'kernel/class', 'Class edit' ) ) );
257             return $Result;
258         }
259     }
260 }
261
262 include_once( 'kernel/classes/ezdatatype.php' );
263 eZDataType::loadAndRegisterAllTypes();
264 $datatypes = eZDataType::registeredDataTypes();
265
266 $customAction = false;
267 $customActionAttributeID = null;
268 // Check for custom actions
269 if ( $http->hasPostVariable( 'CustomActionButton' ) )
270 {
271     $customActionArray = $http->postVariable( 'CustomActionButton' );
272     $customActionString = key( $customActionArray );
273
274     $customActionAttributeID = preg_match( "#^([0-9]+)_(.*)$#", $customActionString, $matchArray );
275
276     $customActionAttributeID = $matchArray[1];
277     $customAction = $matchArray[2];
278 }
279
280
281 // Validate input
282 $storeActions = array( 'MoveUp',
283                        'MoveDown',
284                        'StoreButton',
285                        'ApplyButton',
286                        'NewButton',
287                        'CustomActionButton');
288 $validationRequired = false;
289 foreach( $storeActions as $storeAction )
290 {
291     if ( $http->hasPostVariable( $storeAction ) )
292     {
293         $validationRequired = true;
294         break;
295     }
296 }
297
298 include_once( 'lib/ezutils/classes/ezinputvalidator.php' );
299 $canStore = true;
300 $requireFixup = false;
301 if ( $contentClassHasInput )
302 {
303     if ( $validationRequired )
304     {
305         foreach ( array_keys( $attributes ) as $key )
306         {
307             $attribute =& $attributes[$key];
308             $dataType = $attribute->dataType();
309             $status = $dataType->validateClassAttributeHTTPInput( $http, 'ContentClass', $attribute );
310             if ( $status == EZ_INPUT_VALIDATOR_STATE_INTERMEDIATE )
311                 $requireFixup = true;
312             else if ( $status == EZ_INPUT_VALIDATOR_STATE_INVALID )
313             {
314                 $canStore = false;
315                 $attributeName = $dataType->attribute( 'information' );
316                 $attributeName = $attributeName['name'];
317                 $unvalidatedAttributes[] = array( 'id' => $attribute->attribute( 'id' ),
318                                                   'identifier' => $attribute->attribute( 'identifier' ) ? $attribute->attribute( 'identifier' ) : $attribute->attribute( 'name' ),
319                                                   'name' => $attributeName );
320             }
321         }
322         $validation['processed'] = true;
323         $validation['attributes'] = $unvalidatedAttributes;
324         $requireVariable = 'ContentAttribute_is_required_checked';
325         $searchableVariable = 'ContentAttribute_is_searchable_checked';
326         $informationCollectorVariable = 'ContentAttribute_is_information_collector_checked';
327         $canTranslateVariable = 'ContentAttribute_can_translate_checked';
328         $requireCheckedArray = array();
329         $searchableCheckedArray = array();
330         $informationCollectorCheckedArray = array();
331         $canTranslateCheckedArray = array();
332         if ( $http->hasPostVariable( $requireVariable ) )
333             $requireCheckedArray = $http->postVariable( $requireVariable );
334         if ( $http->hasPostVariable( $searchableVariable ) )
335             $searchableCheckedArray = $http->postVariable( $searchableVariable );
336         if ( $http->hasPostVariable( $informationCollectorVariable ) )
337             $informationCollectorCheckedArray = $http->postVariable( $informationCollectorVariable );
338         if ( $http->hasPostVariable( $canTranslateVariable ) )
339             $canTranslateCheckedArray = $http->postVariable( $canTranslateVariable );
340
341         if ( $http->hasPostVariable( 'ContentAttribute_priority' ) )
342             $placementArray = $http->postVariable( 'ContentAttribute_priority' );
343
344         foreach ( array_keys( $attributes ) as $key )
345         {
346             $attribute =& $attributes[$key];
347             $attributeID = $attribute->attribute( 'id' );
348             $attribute->setAttribute( 'is_required', in_array( $attributeID, $requireCheckedArray ) );
349             $attribute->setAttribute( 'is_searchable', in_array( $attributeID, $searchableCheckedArray ) );
350             $attribute->setAttribute( 'is_information_collector', in_array( $attributeID, $informationCollectorCheckedArray ) );
351             // Set can_translate to 0 if user has clicked Disable translation in GUI
352             $attribute->setAttribute( 'can_translate', !in_array( $attributeID, $canTranslateCheckedArray ) );
353
354             $placement = (int) $placementArray[$key];
355             if ( $attribute->attribute( 'placement' ) != $placement )
356                 $attribute->setAttribute( 'placement', $placement );
357         }
358     }
359 }
360
361 // Fixup input
362 if ( $requireFixup )
363 {
364     foreach( array_keys( $attributes ) as $key )
365     {
366         $attribute =& $attributes[$key];
367         $dataType = $attribute->dataType();
368         $status = $dataType->fixupClassAttributeHTTPInput( $http, 'ContentClass', $attribute );
369     }
370 }
371
372 $cur_datatype = 'ezstring';
373 // Apply HTTP POST variables
374 if ( $contentClassHasInput )
375 {
376     eZHTTPPersistence::fetch( 'ContentAttribute', eZContentClassAttribute::definition(), $attributes, $http, true );
377     if ( $http->hasPostVariable( 'ContentAttribute_name' ) )
378     {
379         $attributeNames = $http->postVariable( 'ContentAttribute_name' );
380         foreach( array_keys( $attributes ) as $key )
381         {
382             if ( isset( $attributeNames[$key] ) )
383             {
384                 $attributes[$key]->setName( $attributeNames[$key], $EditLanguage );
385             }
386         }
387     }
388
389     eZHTTPPersistence::fetch( 'ContentClass', eZContentClass::definition(), $class, $http, false );
390     if ( $http->hasPostVariable( 'ContentClass_name' ) )
391     {
392         $class->setName( $http->postVariable( 'ContentClass_name' ), $EditLanguage );
393     }
394
395     if ( $http->hasVariable( 'ContentClass_is_container_exists' ) )
396     {
397         if ( $http->hasVariable( 'ContentClass_is_container_checked' ) )
398         {
399             $class->setAttribute( "is_container", 1 );
400         }
401         else
402         {
403             $class->setAttribute( "is_container", 0 );
404         }
405     }
406
407     if ( $http->hasVariable( 'ContentClass_always_available_exists' ) )
408     {
409         if ( $http->hasVariable( 'ContentClass_always_available' ) )
410         {
411             $class->setAttribute( 'always_available', 1 );
412         }
413         else
414         {
415             $class->setAttribute( 'always_available', 0 );
416         }
417     }
418
419     if ( $http->hasVariable( 'ContentClass_default_sorting_exists' ) )
420     {
421         if ( $http->hasVariable( 'ContentClass_default_sorting_field' ) )
422         {
423             $sortingField = $http->variable( 'ContentClass_default_sorting_field' );
424             $class->setAttribute( 'sort_field', $sortingField );
425         }
426         if ( $http->hasVariable( 'ContentClass_default_sorting_order' ) )
427         {
428             $sortingOrder = $http->variable( 'ContentClass_default_sorting_order' );
429             $class->setAttribute( 'sort_order', $sortingOrder );
430         }
431     }
432
433     if ( $http->hasPostVariable( 'DataTypeString' ) )
434         $cur_datatype = $http->postVariable( 'DataTypeString' );
435 }
436
437 $class->setAttribute( 'version', EZ_CLASS_VERSION_STATUS_TEMPORARY );
438 $class->NameList->setHasDirtyData();
439
440 include_once( 'lib/ezi18n/classes/ezchartransform.php' );
441 $trans =& eZCharTransform::instance();
442
443 // Fixed identifiers to only contain a-z0-9_
444 foreach( array_keys( $attributes ) as $key )
445 {
446     $attribute =& $attributes[$key];
447     $attribute->setAttribute( 'version', EZ_CLASS_VERSION_STATUS_TEMPORARY );
448     $identifier = $attribute->attribute( 'identifier' );
449     if ( $identifier == '' )
450         $identifier = $attribute->attribute( 'name' );
451
452     $identifier = $trans->transformByGroup( $identifier, 'identifier' );
453     $attribute->setAttribute( 'identifier', $identifier );
454     $dataType = $attribute->dataType();
455     $dataType->initializeClassAttribute( $attribute );
456 }
457
458 // Fixed class identifier to only contain a-z0-9_
459 $identifier = $class->attribute( 'identifier' );
460 if ( $identifier == '' )
461     $identifier = $class->attribute( 'name' );
462 $identifier = $trans->transformByGroup( $identifier, 'identifier' );
463 $class->setAttribute( 'identifier', $identifier );
464
465 // Run custom actions if any
466 if ( $customAction )
467 {
468     foreach( array_keys( $attributes ) as $key )
469     {
470         $attribute =& $attributes[$key];
471         if ( $customActionAttributeID == $attribute->attribute( 'id' ) )
472         {
473             $attribute->customHTTPAction( $Module, $http, $customAction );
474         }
475     }
476 }
477 // Set new modification date
478 $date_time = time();
479 $class->setAttribute( 'modified', $date_time );
480 include_once( 'kernel/classes/datatypes/ezuser/ezuser.php' );
481 $user =& eZUser::currentUser();
482 $user_id = $user->attribute( 'contentobject_id' );
483 $class->setAttribute( 'modifier_id', $user_id );
484
485 // Remove attributes which are to be deleted
486 if ( $http->hasPostVariable( 'RemoveButton' ) )
487 {
488     $validation['processed'] = true;
489     if ( eZHttpPersistence::splitSelected( 'ContentAttribute', $attributes,
490                                            $http, 'id',
491                                            $keepers, $rejects ) )
492     {
493         $attributes = $keepers;
494         foreach ( $rejects as $reject )
495         {
496             $dataType = $reject->dataType();
497             if ( $dataType->isClassAttributeRemovable( $reject ) )
498             {
499                 $reject->remove();
500             }
501             else
502             {
503                 $removeInfo = $dataType->classAttributeRemovableInformation( $reject );
504                 if ( $removeInfo !== false )
505                 {
506                     $validation['attributes'] = array( array( 'id' => $reject->attribute( 'id' ),
507                                                               'identifier' => $reject->attribute( 'identifier' ),
508                                                               'reason' => $removeInfo ) );
509                 }
510             }
511         }
512     }
513 }
514
515 // Fetch HTTP input
516 if ( $contentClassHasInput )
517 {
518     foreach( array_keys( $attributes ) as $key )
519     {
520         $attribute =& $attributes[$key];
521         $dataType = $attribute->dataType();
522         $dataType->fetchClassAttributeHTTPInput( $http, 'ContentClass', $attribute );
523     }
524 }
525
526 if ( $validationRequired )
527 {
528     // check for duplicate attribute identifiers in the input
529     if ( count( $attributes ) > 1 )
530     {
531         for( $attrIndex = 0; $attrIndex < count( $attributes ) - 1; $attrIndex++ )
532         {
533             $classAttribute = $attributes[$attrIndex];
534             $identifier = $classAttribute->attribute( 'identifier' );
535             $placement = $classAttribute->attribute( 'placement' );
536             for ( $attrIndex2 = $attrIndex + 1; $attrIndex2 < count( $attributes ); $attrIndex2++ )
537             {
538                 $classAttribute2 = $attributes[$attrIndex2];
539                 $identifier2 = $classAttribute2->attribute( 'identifier' );
540                 $placement2 = $classAttribute2->attribute( 'placement' );
541                 if (  $placement ==  $placement2 )
542                 {
543                     $validation['attributes'][] = array( 'identifier' => $identifier2,
544                                                          'name' => $classAttribute2->attribute( 'name' ),
545                                                          'id' => $classAttribute2->attribute( 'id' ),
546                                                          'reason' => array ( 'text' => 'duplicate attribute placement' ) );
547                     $canStore = false;
548                     break;
549                 }
550
551                 if ( $identifier == $identifier2 )
552                 {
553                     $validation['attributes'][] = array( 'identifier' => $identifier,
554                                                          'name' => $classAttribute->attribute( 'name' ),
555                                                          'id' => $classAttribute->attribute( 'id' ),
556                                                          'reason' => array ( 'text' => 'duplicate attribute identifier' ) );
557                     $canStore = false;
558                     break;
559                 }
560             }
561         }
562     }
563 }
564
565 // Store version 0 and discard version 1
566 if ( $http->hasPostVariable( 'StoreButton' ) && $canStore )
567 {
568
569     $id = $class->attribute( 'id' );
570     $oldClassAttributes = $class->fetchAttributes( $id, true, EZ_CLASS_VERSION_STATUS_DEFINED );
571     $newClassAttributes = $class->fetchAttributes( );
572
573     // validate class name and identifier; check presence of class attributes
574     // FIXME: object pattern name is never validated
575
576     $basicClassPropertiesValid = true;
577     {
578         $className       =& $class->attribute( 'name' );
579         $classIdentifier =& $class->attribute( 'identifier' );
580         $classID         =& $class->attribute( 'id' );
581
582         // validate class name
583         if( trim( $className ) == '' )
584         {
585             $validation['class_errors'][] = array( 'text' => ezi18n( 'kernel/class', 'The class should have nonempty \'Name\' attribute.' ) );
586             $basicClassPropertiesValid = false;
587         }
588
589         // check presence of attributes
590         $newClassAttributes = $class->fetchAttributes( );
591         if ( count( $newClassAttributes ) == 0 )
592         {
593             $validation['class_errors'][] = array( 'text' => ezi18n( 'kernel/class', 'The class should have at least one attribute.' ) );
594             $basicClassPropertiesValid = false;
595         }
596
597         // validate class identifier
598
599         $db =& eZDB::instance();
600         $classCount = $db->arrayQuery( "SELECT COUNT(*) AS count FROM ezcontentclass WHERE  identifier='$classIdentifier' AND version=" . EZ_CLASS_VERSION_STATUS_DEFINED . " AND id <> $classID" );
601         if ( $classCount[0]['count'] > 0 )
602         {
603             $validation['class_errors'][] = array( 'text' => ezi18n( 'kernel/class', 'There is a class already having the same identifier.' ) );
604             $basicClassPropertiesValid = false;
605         }
606         unset( $classList );
607         unset( $db );
608     }
609
610     if ( !$basicClassPropertiesValid )
611     {
612         $canStore = false;
613         $validation['processed'] = false;
614     }
615     else
616     {
617         $firstStoreAttempt =& eZSessionRead( $http->sessionVariable( 'CanStoreTicket' ) );
618         if ( !$firstStoreAttempt )
619         {
620             return $Module->redirectToView( 'view', array( $ClassID ), array( 'Language' => $EditLanguage ) );
621         }
622         eZSessionDestroy( $http->sessionVariable( 'CanStoreTicket' ) );
623
624         // Class cleanup, update existing class objects according to new changes
625         include_once( 'kernel/classes/ezcontentobject.php' );
626
627         $objects = null;
628         $objectCount = eZContentObject::fetchSameClassListCount( $ClassID );
629         if ( $objectCount > 0 )
630         {
631             // Delete object attributes which have been removed.
632             foreach ( $oldClassAttributes as $oldClassAttribute )
633             {
634                 $attributeExist = false;
635                 $oldClassAttributeID = $oldClassAttribute->attribute( 'id' );
636                 foreach ( $newClassAttributes as $newClassAttribute )
637                 {
638                     $newClassAttributeID = $newClassAttribute->attribute( 'id' );
639                     if ( $oldClassAttributeID == $newClassAttributeID )
640                         $attributeExist = true;
641                 }
642                 if ( !$attributeExist )
643                 {
644                     $objectAttributes = eZContentObjectAttribute::fetchSameClassAttributeIDList( $oldClassAttributeID );
645                     foreach ( $objectAttributes as $objectAttribute )
646                     {
647                         $objectAttributeID = $objectAttribute->attribute( 'id' );
648                         $objectAttribute->remove( $objectAttributeID );
649                     }
650                 }
651             }
652             $class->storeDefined( $attributes );
653
654             // Add object attributes which have been added.
655             foreach ( $newClassAttributes as $newClassAttribute )
656             {
657                 $attributeExist = false;
658                 $newClassAttributeID = $newClassAttribute->attribute( 'id' );
659                 foreach ( $oldClassAttributes as $oldClassAttribute )
660                 {
661                     $oldClassAttributeID = $oldClassAttribute->attribute( 'id' );
662                     if ( $oldClassAttributeID == $newClassAttributeID )
663                         $attributeExist = true;
664                 }
665                 if ( !$attributeExist )
666                 {
667                     if ( $objects == null )
668                     {
669                         $objects = eZContentObject::fetchSameClassList( $ClassID );
670                     }
671                     foreach ( $objects as $object )
672                     {
673                         $contentobjectID = $object->attribute( 'id' );
674                         $objectVersions =& $object->versions();
675                         foreach ( $objectVersions as $objectVersion )
676                         {
677                             $translations = $objectVersion->translations( false );
678                             $version = $objectVersion->attribute( 'version' );
679                             foreach ( $translations as $translation )
680                             {
681                                 $objectAttribute = eZContentObjectAttribute::create( $newClassAttributeID, $contentobjectID, $version );
682                                 $objectAttribute->setAttribute( 'language_code', $translation );
683                                 $objectAttribute->initialize();
684                                 $objectAttribute->store();
685                                 $objectAttribute->postInitialize();
686                             }
687                         }
688                     }
689                 }
690             }
691         }
692         else
693         {
694             $class->storeDefined( $attributes );
695         }
696
697         $http->removeSessionVariable( 'CanStoreTicket' );
698         return $Module->redirectToView( 'view', array( $ClassID ), array( 'Language' => $EditLanguage ) );
699     }
700 }
701
702 // Store changes
703 if ( $canStore )
704     $class->store( $attributes );
705
706 if ( $http->hasPostVariable( 'NewButton' ) )
707 {
708     $new_attribute = eZContentClassAttribute::create( $ClassID, $cur_datatype, array(), $EditLanguage );
709     $attrcnt = count( $attributes ) + 1;
710     $new_attribute->setName( ezi18n( 'kernel/class/edit', 'new attribute' ) . $attrcnt, $EditLanguage );
711     $dataType = $new_attribute->dataType();
712     $dataType->initializeClassAttribute( $new_attribute );
713     $new_attribute->store();
714     $attributes[] =& $new_attribute;
715 }
716 else if ( $http->hasPostVariable( 'MoveUp' ) )
717 {
718     $attribute =& eZContentClassAttribute::fetch( $http->postVariable( 'MoveUp' ), true, EZ_CLASS_VERSION_STATUS_TEMPORARY,
719                                                   array( 'contentclass_id', 'version', 'placement' ) );
720     $attribute->move( false );
721     $Module->redirectTo( $Module->functionURI( 'edit' ) . '/' . $ClassID );
722     return;
723 }
724 else if ( $http->hasPostVariable( 'MoveDown' ) )
725 {
726     $attribute =& eZContentClassAttribute::fetch( $http->postVariable( 'MoveDown' ), true, EZ_CLASS_VERSION_STATUS_TEMPORARY,
727                                                   array( 'contentclass_id', 'version', 'placement' ) );
728     $attribute->move( true );
729     $Module->redirectTo( $Module->functionURI( 'edit' ) . '/' . $ClassID );
730     return;
731 }
732
733 $Module->setTitle( 'Edit class ' . $class->attribute( 'name' ) );
734 if ( !$http->hasSessionVariable( 'CanStoreTicket' ) )
735 {
736     $http->setSessionVariable( 'CanStoreTicket', md5( (string)rand() ) );
737     eZSessionWrite( $http->sessionVariable( 'CanStoreTicket' ), 1 );
738 }
739
740 // Fetch updated attributes
741 $attributes = $class->fetchAttributes();
742
743 // Template handling
744 include_once( 'kernel/common/template.php' );
745 $tpl =& templateInit();
746 $res =& eZTemplateDesignResource::instance();
747 $res->setKeys( array( array( 'class', $class->attribute( 'id' ) ) ) ); // Class ID
748 $tpl->setVariable( 'http', $http );
749 $tpl->setVariable( 'validation', $validation );
750 $tpl->setVariable( 'can_store', $canStore );
751 $tpl->setVariable( 'require_fixup', $requireFixup );
752 $tpl->setVariable( 'module', $Module );
753 $tpl->setVariable( 'class', $class );
754 $tpl->setVariable( 'attributes', $attributes );
755 $tpl->setVariable( 'datatypes', $datatypes );
756 $tpl->setVariable( 'datatype', $cur_datatype );
757 $tpl->setVariable( 'language_code', $EditLanguage );
758
759 $Result = array();
760 $Result['content'] =& $tpl->fetch( 'design:class/edit.tpl' );
761 $Result['path'] = array( array( 'url' => '/class/edit/',
762                                 'text' => ezi18n( 'kernel/class', 'Class edit' ) ) );
763
764 ?>