Overview

Packages

  • application
    • commands
    • components
      • actions
      • filters
      • leftWidget
      • permissions
      • sortableWidget
      • util
      • webupdater
      • x2flow
        • actions
        • triggers
      • X2GridView
      • X2Settings
    • controllers
    • models
      • embedded
    • modules
      • accounts
        • controllers
        • models
      • actions
        • controllers
        • models
      • calendar
        • controllers
        • models
      • charts
        • models
      • contacts
        • controllers
        • models
      • docs
        • components
        • controllers
        • models
      • groups
        • controllers
        • models
      • marketing
        • components
        • controllers
        • models
      • media
        • controllers
        • models
      • mobile
        • components
      • opportunities
        • controllers
        • models
      • products
        • controllers
        • models
      • quotes
        • controllers
        • models
      • services
        • controllers
        • models
      • template
        • models
      • users
        • controllers
        • models
      • workflow
        • controllers
        • models
      • x2Leads
        • controllers
        • models
  • None
  • system
    • base
    • caching
    • console
    • db
      • ar
      • schema
    • validators
    • web
      • actions
      • auth
      • helpers
      • widgets
        • captcha
        • pagers
  • zii
    • widgets
      • grid

Classes

  • MediaController
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: 
  3: /*****************************************************************************************
  4:  * X2Engine Open Source Edition is a customer relationship management program developed by
  5:  * X2Engine, Inc. Copyright (C) 2011-2016 X2Engine Inc.
  6:  * 
  7:  * This program is free software; you can redistribute it and/or modify it under
  8:  * the terms of the GNU Affero General Public License version 3 as published by the
  9:  * Free Software Foundation with the addition of the following permission added
 10:  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
 11:  * IN WHICH THE COPYRIGHT IS OWNED BY X2ENGINE, X2ENGINE DISCLAIMS THE WARRANTY
 12:  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
 13:  * 
 14:  * This program is distributed in the hope that it will be useful, but WITHOUT
 15:  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 16:  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
 17:  * details.
 18:  * 
 19:  * You should have received a copy of the GNU Affero General Public License along with
 20:  * this program; if not, see http://www.gnu.org/licenses or write to the Free
 21:  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 22:  * 02110-1301 USA.
 23:  * 
 24:  * You can contact X2Engine, Inc. P.O. Box 66752, Scotts Valley,
 25:  * California 95067, USA. or at email address contact@x2engine.com.
 26:  * 
 27:  * The interactive user interfaces in modified source and object code versions
 28:  * of this program must display Appropriate Legal Notices, as required under
 29:  * Section 5 of the GNU Affero General Public License version 3.
 30:  * 
 31:  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
 32:  * these Appropriate Legal Notices must retain the display of the "Powered by
 33:  * X2Engine" logo. If the display of the logo is not reasonably feasible for
 34:  * technical reasons, the Appropriate Legal Notices must display the words
 35:  * "Powered by X2Engine".
 36:  *****************************************************************************************/
 37: 
 38: /**
 39:  * @package application.modules.media.controllers
 40:  */
 41: class MediaController extends x2base {
 42: 
 43:     public $modelClass = "Media";
 44: 
 45:     public function behaviors() {
 46:         return array_merge(parent::behaviors(), array(
 47:                 /*
 48:                   uncomment when media module supports custom forms
 49:                   'QuickCreateRelationshipBehavior' => array(
 50:                   'class' => 'QuickCreateRelationshipBehavior',
 51:                   ), */
 52:         ));
 53:     }
 54: 
 55:     public function checkPermissions(&$model, $action = null) {
 56:         if ($model instanceof Media) {
 57:             return Yii::app()->params->isAdmin ||
 58:                     (!$model->private || $model->uploadedBy === Yii::app()->user->name) &&
 59:                     $this->asa('PermissionsBehavior')->checkPermissions($model, $action);
 60:         } else {
 61:             return $this->asa('PermissionsBehavior')->checkPermissions($model, $action);
 62:         }
 63:     }
 64: 
 65:     /**
 66:      * @var string the default layout for the views. Defaults to '//layouts/column2', meaning
 67:      * using two-column layout. See 'protected/views/layouts/column2.php'.
 68:      */
 69: 
 70:     /**
 71:      * Displays a particular model.
 72:      * @param integer $id the ID of the model to be displayed
 73:      */
 74:     public function actionView($id) {
 75:         $model = $this->loadModel($id);
 76:         if (!$this->checkPermissions($model, 'view'))
 77:             $this->denied();
 78: 
 79:         // add media object to user's recent item list
 80:         User::addRecentItem('m', $id, Yii::app()->user->getId());
 81: 
 82:         $model = $this->loadModel($id);
 83: 
 84:         $this->insertMenu(array(
 85:             'index', 'upload', 'view', 'edit', 'delete', 'editLayout',
 86:                 ), $model);
 87: 
 88:         $this->render('view', array(
 89:             'model' => $model,
 90:         ));
 91:     }
 92: 
 93:     /**
 94:      * Forces download of specified media file
 95:      */
 96:     public function actionDownload($id) {
 97:         $model = $this->loadModel($id);
 98:         if (!$this->checkPermissions($model, 'view'))
 99:             $this->denied();
100:         $filePath = $model->getPath();
101:         if ($filePath != null)
102:             $file = Yii::app()->file->set($filePath);
103:         else
104:             throw new CHttpException(404);
105:         if ($file->exists)
106:             $file->send();
107:         //Yii::app()->getRequest()->sendFile($model->fileName,@file_get_contents($fileName));
108:         $this->redirect(array('view', 'id' => $id));
109:     }
110: 
111:     /**
112:      * Alias for actionUpload
113:      */
114:     public function actionCreate() {
115:         $this->actionUpload();
116:     }
117: 
118:     private function createAttachmentAction($model) {
119:         if (!empty($model->associationType) && !empty($model->associationId) &&
120:                 is_numeric($model->associationId)) {
121: 
122:             $note = new Actions;
123:             $note->createDate = time();
124:             $note->dueDate = time();
125:             $note->completeDate = time();
126:             $note->complete = 'Yes';
127:             $note->visibility = '1';
128:             $note->completedBy = Yii::app()->user->getName();
129:             if ($model->private) {
130:                 $note->assignedTo = Yii::app()->user->getName();
131:                 $note->visibility = '0';
132:             } else {
133:                 $note->assignedTo = 'Anyone';
134:             }
135:             $note->type = 'attachment';
136:             $note->associationId = $model->associationId;
137:             $note->associationType = $model->associationType;
138:             if ($modelName = X2Model::getModelName($model->associationType)) {
139:                 $association = X2Model::model($modelName)->findByPk($model->associationId);
140:                 if ($association != null) {
141:                     $note->associationName = $association->name;
142:                 }
143:             }
144:             $note->actionDescription = $model->fileName . ':' . $model->id;
145:             return $note->save();
146:         }
147:         return false;
148:     }
149: 
150:     public function actionQtip($id) {
151:         $model = Media::model()->findByPk($id);
152:         $this->renderPartial('qtip', array('model' => $model));
153:     }
154: 
155:     /**
156:      * Creates a new model.
157:      * If creation is successful, the browser will be redirected to the 'view' page.
158:      */
159:     public function actionUpload() {
160:         $model = new Media;
161: 
162:         if (isset($_POST['Media'])) {
163: 
164:             $temp = TempFile::model()->findByPk($_POST['TempFileId']);
165: 
166:             $userFolder = Yii::app()->user->name; // place uploaded files in a folder named with the username of the user that uploaded the file
167:             $userFolderPath = 'uploads/protected/media/' . $userFolder;
168:             // if user folder doesn't exit, try to create it
169:             if (!(file_exists($userFolderPath) && is_dir($userFolderPath))) {
170:                 if (!@mkdir('uploads/protected/media/' . $userFolder, 0777, true)) { // make dir with edit permission
171:                     // ERROR: Couldn't create user folder
172:                     var_dump($userFolder);
173:                     exit();
174:                 }
175:             }
176: 
177:             rename($temp->fullpath(), $userFolderPath . '/' . $temp->name);
178: 
179:             // save media info
180:             $model->fileName = $temp->name;
181:             $model->createDate = time();
182:             $model->lastUpdated = time();
183:             $model->uploadedBy = Yii::app()->user->name;
184:             $model->setAttributes($_POST['Media']);
185:             $model->path; // File type setter is embedded in the magic getter for path
186: 
187:             if (empty($model->name))
188:                 $model->name = $model->fileName;
189: 
190:             if (empty($model->associationType)) {
191:                 $model->associationType = 'none';
192:             }
193: 
194: 
195:             if ($model->save()) {
196:                 $this->createAttachmentAction($model);
197:                 $this->redirect(array('view', 'id' => $model->id));
198:             }
199:         }
200: 
201:         /*
202:           uncomment when media module supports custom forms
203:           if(isset($_POST['x2ajax'])){
204:           $this->renderInlineCreateForm ($model, isset ($ajaxErrors) ? $ajaxErrors : false);
205:           } else { */
206:         $this->render('upload', array(
207:             'model' => $model,
208:         ));
209:         //}
210:     }
211: 
212:     /**
213:      * Creates a new media object via an ajax upload
214:      *
215:      */
216:     public function actionAjaxUpload() {
217: 
218:         $fileUrl = '';
219: 
220:         try {
221:             if (Yii::app()->user->isGuest)
222:                 throw new Exception('You are not logged in.');
223: 
224:             if (!isset($_FILES['upload'], $_GET['CKEditorFuncNum'])) //,$_GET['Media']
225:                 throw new Exception('Invalid request.');
226: 
227:             $upload = CUploadedFile::getInstanceByName('upload');
228: 
229:             if ($upload == null)
230:                 throw new Exception('Invalid file.');
231: 
232:             $fileName = $upload->getName();
233:             $fileName = str_replace(' ', '_', $fileName);
234: 
235:             $userFolder = Yii::app()->user->name; // place uploaded files in a folder named with the username of the user that uploaded the file
236:             $userFolderPath = 'uploads/protected/media/' . $userFolder;
237:             // if user folder doesn't exit, try to create it
238:             if (!(file_exists($userFolderPath) && is_dir($userFolderPath))) {
239:                 if (!@mkdir('uploads/protected/media/' . $userFolder, 0777, true)) { // make dir with edit permission
240:                     throw new Exception('Error creating user folder.');
241:                 }
242:             }
243: 
244:             if (!$upload->saveAs($userFolderPath . DIRECTORY_SEPARATOR . $fileName))
245:                 throw new Exception('Error saving file');
246: 
247:             // save media info
248:             $model = new Media;
249:             $model->fileName = $fileName;
250:             $model->createDate = time();
251:             $model->lastUpdated = time();
252:             $model->uploadedBy = Yii::app()->user->name;
253:             $model->associationType = 'none';
254: 
255:             if (!$model->save()) {
256:                 throw new Exception('Error saving Media entry');
257:             }
258: 
259:             $fileUrl = $model->getFullUrl();
260:         } catch (Exception $e) {
261:             echo '<html><body><script type="text/javascript">',
262:             'window.parent.CKEDITOR.tools.callFunction(', json_encode($_GET['CKEditorFuncNum']), ',"","', $e->getMessage(), '");',
263:             '</script></body></html>';
264:             return;
265:         }
266:         echo '<html><body><script type="text/javascript">',
267:         'window.parent.CKEDITOR.tools.callFunction(', json_encode($_GET['CKEditorFuncNum']), ',"', json_encode($fileUrl), '","");',
268:         '</script></body></html>';
269:     }
270: 
271:     /**
272:      * Updates a particular model.
273:      * If update is successful, the browser will be redirected to the 'view' page.
274:      * @param integer $id the ID of the model to be updated
275:      */
276:     public function actionUpdate($id) {
277:         $model = $this->loadModel($id);
278:         if (!$this->checkPermissions($model, 'edit'))
279:             $this->denied();
280: 
281:         if (isset($_POST['Media'])) {
282:             // save media info
283:             $model->lastUpdated = time();
284:             $model->associationType = $_POST['Media']['associationType'];
285:             $model->associationId = $_POST['Media']['associationId'];
286:             $model->private = $_POST['Media']['private'];
287:             if ($_POST['Media']['description'])
288:                 $model->description = $_POST['Media']['description'];
289:             if (!$model->drive) {
290:                 // Handle setting the name if the Media isn't stored on Drive
291:                 $model->name = $_POST['Media']['name'];
292:                 if (empty($model->name))
293:                     $model->name = $model->fileName;
294:             }
295:             if ($model->save())
296:                 $this->redirect(array('view', 'id' => $model->id));
297:         }
298: 
299:         $this->render('update', array(
300:             'model' => $model,
301:         ));
302:     }
303: 
304:     /**
305:      * Deletes a particular model.
306:      * If deletion is successful, the browser will be redirected to the 'admin' page.
307:      * @param integer $id the ID of the model to be deleted
308:      */
309:     public function actionDelete($id) {
310:         if (Yii::app()->request->isPostRequest) {
311:             // we only allow deletion via POST request
312:             $model = $this->loadModel($id);
313:             if (!$this->checkPermissions($model, 'delete'))
314:                 $this->denied();
315:             $model->delete();
316: 
317:             // if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser
318:             if (!isset($_GET['ajax']))
319:                 $this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('index'));
320:         } else
321:             throw new CHttpException(400, Yii::t('app', 'Invalid request. Please do not repeat this request again.'));
322:     }
323: 
324:     /**
325:      * Lists all models.
326:      */
327:     public function actionIndex() {
328:         $model = new Media('search');
329:         if (isset($_GET['Media'])) {
330:             foreach ($_GET['Media'] as $key => $value) {
331:                 if ($model->hasAttribute($key))
332:                     $model->$key = $value;
333:             }
334:         }
335:         $this->render('index', array(
336:             'model' => $model,
337:         ));
338:     }
339: 
340: //    public function actionTestDrive(){
341: //        $admin = Yii::app()->settings;
342: //        if(isset($_REQUEST['logout'])){
343: //            unset($_SESSION['access_token']);
344: //        }
345: //        require_once('protected/components/GoogleAuthenticator.php');
346: //        $auth = new GoogleAuthenticator();
347: //        if($auth->getAccessToken()){
348: //            $service = $auth->getDriveService();
349: //        }
350: //        $createdFile = null;
351: //        if(isset($service, $_SESSION['access_token'], $_FILES['upload'])){
352: //            $file = new Google_Service_Drive_DriveFile();
353: //            $file->setTitle($_FILES['upload']['name']);
354: //            $file->setDescription('Uploaded by X2Engine');
355: //            $file->setMimeType($_FILES['upload']['type']);
356: //
357: //            $data = file_get_contents($_FILES['upload']['tmp_name']);
358: //            try{
359: //                $createdFile = $service->files->insert($file, array(
360: //                    'data' => $data,
361: //                    'mimeType' => $_FILES['upload']['type'],
362: //                        ));
363: //                if(is_array($createdFile)){
364: //                    $media = new Media;
365: //                    $media->fileName = $createdFile['id'];
366: //                    $media->name = $createdFile['title'];
367: //                    $media->associationType = 'Contacts';
368: //                    $media->associationId = 955;
369: //                    $media->uploadedBy = Yii::app()->user->getName();
370: //                    $media->mimetype = $createdFile['mimeType'];
371: //                    $media->filesize = $createdFile['fileSize'];
372: //                    $media->drive = 1;
373: //                    $media->save();
374: //                }
375: //            }catch(Google_Auth_Exception $e){
376: //                unset($_SESSION['access_token']);
377: //                $auth->setErrors($e->getMessage());
378: //                $service = null;
379: //                $createdFile = null;
380: //            }
381: //        }
382: //
383: //        $this->render('testDrive', array(
384: //            'auth' => $auth,
385: //            'createdFile' => $createdFile,
386: //            'service' => isset($service) ? $service : null,
387: //            'baseFolder' => isset($service) ? $this->printFolder('root', $auth) : null
388: //        ));
389: //    }
390: 
391:     public function actionRecursiveDriveFiles($folderId) {
392:         $ret = $this->printFolder($folderId);
393:         echo $ret;
394:     }
395: 
396:     public function printFolder($folderId, $auth = null) {
397:         if (is_null($auth)) {
398:             $auth = new GoogleAuthenticator();
399:         }
400:         $service = $auth->getDriveService();
401:         try {
402:             if ($service) {
403:                 $ret = "";
404:                 $files = $service->files;
405:                 $fileList = $files->listFiles(array('q' => 'trashed=false and "' . $folderId . '" in parents'));
406:                 $folderList = array();
407:                 $fileArray = array();
408:                 foreach ($fileList['items'] as $file) {
409:                     if ($file['mimeType'] == 'application/vnd.google-apps.folder') {
410:                         $folderList[] = $file;
411:                     } else {
412:                         $fileArray[] = $file;
413:                     }
414:                 }
415:                 $fileList = array_merge($folderList, $fileArray);
416:                 foreach ($fileList as $file) {
417:                     if ($file['mimeType'] == 'application/vnd.google-apps.folder') {
418:                         $ret .= "<div class='drive-wrapper'><div class='drive-item'><div class='drive-icon' style='background:url(\"" . $file['iconLink'] . "\") no-repeat'></div><a href='#' class='toggle-file-system drive-link' data-id='{$file['id']}'> " . $file['title'] . "</a></div></div>";
419:                         $ret .= "<div class='drive' id='{$file['id']}' style='display:none;'>";
420:                         $ret .= "</div>";
421:                     } else {
422:                         $ret .= "<div class='drive-wrapper'><div class='drive-item'><div class='drive-icon' style='background:url(\"" . $file['iconLink'] . "\") no-repeat'></div> <a class='x2-link drive-link media' href='" . $file['alternateLink'] . "' target='_blank'>" . $file['title'] . "</a></div></div>";
423:                     }
424:                 }
425:                 return $ret;
426:             } else {
427:                 return false;
428:             }
429:         } catch (Google_Auth_Exception $e) {
430:             if (isset($_SESSION['access_token']) || isset($_SESSION['token'])) { // If these are set it's possible the token expired and there is a refresh token available
431:                 $auth->flushCredentials(false); // Only flush the recently received information
432:                 return $this->printFolder($folderId); // Try again, it will use a refresh token if available this time, otherwise it will fail.
433:             } else {
434:                 $auth->flushCredentials();
435:                 $auth->setErrors($e->getMessage());
436:                 return false;
437:             }
438:         } catch (Google_Service_Exception $e) {
439:             $auth->setErrors($e->getMessage());
440:             return false;
441:         }
442:     }
443: 
444:     public function actionRefreshDriveCache() {
445:         $auth = new GoogleAuthenticator();
446:         if ($auth->getAccessToken()) {
447:             if (isset($_SESSION['driveFiles'])) {
448:                 unset($_SESSION['driveFiles']);
449:             }
450:             echo $_SESSION['driveFiles'] = $this->printFolder('root');
451:         }
452:     }
453: 
454:     /**
455:      * Performs the AJAX validation.
456:      * @param CModel the model to be validated
457:      */
458:     protected function performAjaxValidation($model) {
459:         if (isset($_POST['ajax']) && $_POST['ajax'] === 'media-form') {
460:             echo CActiveForm::validate($model);
461:             Yii::app()->end();
462:         }
463:     }
464: 
465:     public function actionToggleUserMediaVisible($user) {
466:         $widgetSettings = json_decode(Yii::app()->params->profile->widgetSettings, true);
467:         $mediaSettings = $widgetSettings['MediaBox'];
468:         $hideUsers = $mediaSettings['hideUsers'];
469:         $ret = '';
470: 
471:         if (($key = array_search($user, $hideUsers)) !== false) { // user is not visible, make them visible
472:             unset($hideUsers[$key]);
473:             $hideUsers = array_values($hideUsers); // reindex array so json is consistent
474:             $ret = 1;
475:         } else { // user is visible, make them not visible
476:             $hideUsers[] = $user;
477:             $ret = 0;
478:         }
479: 
480:         $mediaSettings['hideUsers'] = $hideUsers;
481:         $widgetSettings['MediaBox'] = $mediaSettings;
482:         Yii::app()->params->profile->widgetSettings = json_encode($widgetSettings);
483:         Yii::app()->params->profile->update();
484: 
485:         echo $ret;
486:     }
487: 
488:     public function actionGetItems() {
489:         $model = X2Model::model($this->modelClass);
490:         if (isset($model)) {
491:             list ($accessCond, $params) = $model->getAccessSQLCondition();
492:             $tableName = $model->tableName();
493:             $sql = 'SELECT id, fileName as value
494:                  FROM ' . $tableName . ' 
495:                  WHERE associationType!="theme" and fileName LIKE :qterm AND ' . $accessCond . ' AND
496:                     (uploadedBy=:username OR private=0 OR private=NULL)
497:                  ORDER BY fileName ASC';
498:             $command = Yii::app()->db->createCommand($sql);
499:             $qterm = $_GET['term'] . '%';
500:             $params[':qterm'] = $qterm;
501:             $params[':username'] = Yii::app()->user->getName();
502:             $result = $command->queryAll(true, $params);
503:             echo CJSON::encode($result);
504:         }
505:         Yii::app()->end();
506:     }
507: 
508:     /**
509:      * Create a menu for Media
510:      * @param array Menu options to remove
511:      * @param X2Model Model object passed to the view
512:      * @param array Additional menu parameters
513:      */
514:     public function insertMenu($selectOptions = array(), $model = null, $menuParams = null) {
515:         $Media = Modules::displayName();
516:         $modelId = isset($model) ? $model->id : 0;
517: 
518:         /**
519:          * To show all options:
520:          * $menuOptions = array(
521:          *     'index', 'upload', 'view', 'edit', 'delete',
522:          * );
523:          */
524:         $menuItems = array(
525:             array(
526:                 'name' => 'index',
527:                 'label' => Yii::t('media', 'All {media}', array(
528:                     '{media}' => $Media,
529:                 )),
530:                 'url' => array('index')
531:             ),
532:             array(
533:                 'name' => 'upload',
534:                 'label' => Yii::t('media', 'Upload'),
535:                 'url' => array('upload')
536:             ),
537:             RecordViewLayoutManager::getViewActionMenuListItem($modelId),
538:             array(
539:                 'name' => 'edit',
540:                 'label' => Yii::t('media', 'Update'),
541:                 'url' => array('update', 'id' => $modelId)
542:             ),
543:             array(
544:                 'name' => 'delete',
545:                 'label' => Yii::t('media', 'Delete'),
546:                 'url' => '#',
547:                 'linkOptions' => array(
548:                     'submit' => array('delete', 'id' => $modelId),
549:                     'confirm' => Yii::t('media', 'Are you sure you want to delete this item?'))
550:             ),
551:             RecordViewLayoutManager::getEditLayoutActionMenuListItem(),
552:         );
553: 
554:         $this->prepareMenu($menuItems, $selectOptions);
555:         $this->actionMenu = $this->formatMenu($menuItems, $menuParams);
556:     }
557: 
558:     /**
559:      * Renders the MediaSelector
560:      * @return Processed html/js/css of the mediaSelector widget
561:      */
562:     public function actionMediaSelector() {
563:         $update = isset($_GET['ajax']);
564: 
565:         $html = $this->widget('application.components.MediaSelector', array(
566:             'update' => $update
567:                 ), true);
568: 
569:         // 'ajax' parameter is set by yiilist view updating
570:         if (!$update) {
571:             $html = $this->processOutput($html);
572:         }
573: 
574:         echo $html;
575:     }
576: 
577:     public function actionGetFile($id, $key = null) {
578:         $model = $this->loadModel($id);
579:         if (!$this->checkPermissions($model, 'view') && $key !== $model->getAccessKey()) {
580:             $this->denied();
581:         }
582:         $model->renderFile();
583:     }
584: 
585: }
586: 
X2CRM Documentation API documentation generated by ApiGen 2.8.0