1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35:
36:
37: 38: 39: 40: 41:
42: class DocFolders extends CActiveRecord {
43:
44: const TEMPLATES_FOLDER_ID = -1;
45:
46: public $module = 'docs';
47:
48: 49: 50: 51:
52: public static function model($className = __CLASS__) {
53: return parent::model($className);
54: }
55:
56: 57: 58:
59: public function tableName() {
60: return 'x2_doc_folders';
61: }
62:
63: public function relations() {
64:
65:
66: return array(
67: 'parent' => array(self::BELONGS_TO, 'DocFolders', 'parentFolder'),
68: 'childFolders' => array(self::HAS_MANY, 'DocFolders', 'parentFolder'),
69: 'childDocs' => array(self::HAS_MANY, 'Docs', 'folderId'),
70: );
71: }
72:
73: 74: 75:
76: public function rules() {
77:
78:
79: return array(
80: array('name, visibility', 'required'),
81: array('parentFolder', 'numerical', 'integerOnly' => true),
82:
83:
84: array('id, name, parentFolder', 'safe', 'on' => 'search'),
85: );
86: }
87:
88: public function attributeLabels() {
89: return array(
90: 'name' => Yii::t('docs', 'Name'),
91: 'visibility' => Yii::t('docs', 'Visibility'),
92: );
93: }
94:
95: 96: 97: 98:
99: public function search() {
100: $criteria = new CDbCriteria;
101: $criteria->compare('id', $this->id);
102: $criteria->compare('name', $this->name);
103: $criteria->compare('parentFolder', $this->parentFolder);
104:
105: return new CActiveDataProvider(get_class($this), array(
106: 'criteria' => $criteria,
107: ));
108: }
109:
110: public function behaviors(){
111: return array(
112: 'X2TimestampBehavior' => array('class' => 'X2TimestampBehavior'),
113: 'permissions' => array('class' => Yii::app()->params->modelPermissions),
114: 'FileSystemObjectBehavior' => array(
115: 'class' => 'application.modules.docs.components.FileSystemObjectBehavior',
116: 'folderRefName' => 'parentFolder',
117: ),
118: );
119: }
120:
121: public function beforeSave(){
122: if(empty($this->createdBy)){
123: $this->createdBy = Yii::app()->user->getName();
124: }
125: $this->updatedBy = Yii::app()->user->getName();
126: return parent::beforeSave();
127: }
128:
129: public function beforeDelete(){
130: $this->deleteRecursive();
131: return parent::beforeDelete();
132: }
133:
134: public function getTemplatesFolderContents() {
135: $contents = $this->findChildren (self::TEMPLATES_FOLDER_ID);
136: return new FileSystemObjectDataProvider($contents, array(
137: 'id' => 'root-folder-contents',
138: 'pagination' => array(
139: 'pageSize' => $this->getPageSize (),
140: )
141: ));
142: }
143:
144: 145: 146: 147:
148: public function findChildren ($folderId='root', array $types=array ('folder', 'doc'),
149: array $exclude=array ()) {
150:
151:
152: $exclude = array_flip ($exclude);
153:
154: if ($folderId === 'root') {
155: $model = self::model ();
156: $fileSysObjs = array ($model->createFileSystemObject ('templates', null));
157: } elseif ($folderId === self::TEMPLATES_FOLDER_ID) {
158: $model = self::model ();
159: $this->id = self::TEMPLATES_FOLDER_ID;
160: $fileSysObjs = array($this->createFileSystemObject ('parent', null));
161: } elseif ($folderId instanceof DocFolders) {
162: $model = $folderId;
163: $fileSysObjs = array($this->createFileSystemObject ('parent', $model->parent));
164: }
165: $children = $model->getChildren ($folderId);
166: foreach ($types as $type) {
167: foreach ($children[$type.'s'] as $child) {
168: $fileSysObjs[] = $this->createFileSystemObject ($type, $child);
169: }
170: }
171:
172: $count = count ($fileSysObjs);
173: for ($i = 0; $i < $count; $i++) {
174: $fileSysObj = $fileSysObjs[$i];
175: if (isset ($exclude[$fileSysObj->objId])) {
176: unset ($fileSysObjs[$i]);
177: }
178: }
179:
180: return $fileSysObjs;
181: }
182:
183: public function getPageSize () {
184: return Profile::getResultsPerPage ();
185: }
186:
187: public function getRootFolderContents($pageSize=null) {
188: if (!$pageSize) $pageSize = $this->getPageSize ();
189: $model = DocFolders::model();
190: $contents = $this->findChildren ();
191: return new FileSystemObjectDataProvider($contents, array(
192: 'id' => 'root-folder-contents',
193: 'pagination' => array(
194: 'pageSize' => $pageSize,
195: )
196: ));
197: }
198:
199: public function checkRecursiveDeletePermissions(){
200: $deletePermission = Yii::app()->controller->checkPermissions($this, 'delete');
201: if (!$deletePermission) {
202: return $deletePermission;
203: }
204: foreach($this->childDocs as $doc){
205: $deletePermission = $deletePermission && Yii::app()->controller->checkPermissions($doc, 'delete');
206: if(!$deletePermission){
207: break;
208: }
209: }
210: if($deletePermission){
211: foreach($this->childFolders as $folder){
212: $deletePermission = $deletePermission && $folder->checkRecursiveDeletePermissions();
213: if(!$deletePermission){
214: break;
215: }
216: }
217: }
218: return $deletePermission;
219: }
220:
221: public function deleteRecursive(){
222: foreach($this->childDocs as $doc){
223: $doc->delete();
224: }
225: foreach($this->childFolders as $folder){
226: $folder->delete();
227: }
228: }
229:
230: public function getPath() {
231: $pathArr = $this->getPathArr();
232: return '/' . implode('/', array_reverse($pathArr));
233: }
234:
235: private function getPathArr() {
236: if (!is_null($this->parent)) {
237: return array_merge(array($this->name), $this->parent->getPathArr());
238: } else {
239: return array($this->name);
240: }
241: }
242:
243: public function getContents() {
244: $contents = array_merge (
245: $this->findChildren ($this));
246: return new FileSystemObjectDataProvider($contents, array(
247: 'id' => $this->id . '-folder-contents',
248: 'pagination' => array(
249: 'pageSize' => $this->getPageSize (),
250: )
251: ));
252: }
253:
254: private function getChildren($option = null) {
255: $children = array('folders' => array(), 'docs' => array());
256: $folderCriteria = new CDbCriteria();
257: if ($option === 'root') {
258: $folderCriteria->condition = 'parentFolder IS NULL AND id > 0';
259: } else {
260: $folderCriteria->compare('parentFolder', $this->id);
261: }
262: $folderCriteria->mergeWith($this->getAccessCriteria());
263: $folderCriteria->order = 'name ASC';
264: $children['folders'] = DocFolders::model()->findAll($folderCriteria);
265:
266: $docsCriteria = new CDbCriteria();
267: $doc = Docs::model();
268: if ($option === 'root') {
269: $docsCriteria->condition = 'folderId IS NULL AND type NOT IN ("email","quote")';
270: } elseif($option === self::TEMPLATES_FOLDER_ID){
271: $docsCriteria->condition = 'folderId IS NULL AND type IN ("email","quote")';
272: } else {
273: $docsCriteria->compare('folderId', $this->id);
274: }
275: $docsCriteria->mergeWith($doc->getAccessCriteria());
276: $docsCriteria->order = 'name ASC';
277: $children['docs'] = Docs::model()->findAll($docsCriteria);
278:
279: return $children;
280: }
281:
282: private function createFileSystemObject($type, $object) {
283: static $id = 0;
284: $options = array(
285: 'id' => $id++,
286: 'parentId' => $this->id,
287: 'type' => null,
288: 'objId' => null,
289: 'name' => null,
290: 'createdBy' => null,
291: 'lastUpdated' => null,
292: 'updatedBy' => null,
293: 'visibility' => null,
294: );
295: if ($type === 'parent') {
296: $options['objId'] = $object ? $object->id : null;
297: $options['type'] = 'folder';
298: $options['name'] = '..';
299: $options['title'] = $object ? $object->name : Yii::t('docs', 'Docs');
300: $options['isParent'] = true;
301: } elseif ($type === 'templates') {
302: $options['type'] = 'folder';
303: $options['objId'] = -1;
304: $options['name'] = Yii::t('docs', 'Templates');
305: } else {
306: $options['type'] = $type;
307: $options['objId'] = $object->id;
308: $options['name'] = $object->name;
309: $options['createdBy'] = $object->createdBy;
310: $options['lastUpdated'] = $object->lastUpdated;
311: $options['updatedBy'] = $object->updatedBy;
312: $options['visibility'] = $object->visibility;
313: }
314: return new FileSystemObject($options);
315: }
316:
317: }
318: