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

  • AdminController
  • Api2Controller
  • ApiController
  • BugReportsController
  • CommonSiteControllerBehavior
  • ProfileController
  • RelationshipsController
  • SearchController
  • SiteController
  • StudioController
  • TemplatesController
  • TopicsController
  • x2base
  • X2Controller
  • 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:  * Primary/default controller for the web application.
  40:  *
  41:  * @package application.controllers
  42:  */
  43: class SiteController extends x2base {
  44: 
  45:     // Declares class-based actions.
  46:     //public $layout = '//layouts/main';
  47: 
  48:     public $modelClass = 'Admin';
  49:     public $portlets = array();
  50: 
  51:     public function filters() {
  52:         return array_merge(parent::filters(), array(
  53:             'setPortlets',
  54:             'accessControl',
  55:         ));
  56:     }
  57: 
  58:     public function behaviors() {
  59:         return array_merge(parent::behaviors(), array(
  60:             'X2MobileControllerBehavior' => array(
  61:                 'class' => 
  62:                     'application.modules.mobile.components.behaviors.'.
  63:                         'X2MobileSiteControllerBehavior'
  64:             ),
  65:             'CommonSiteControllerBehavior' => array(
  66:                 'class' => 'application.components.CommonSiteControllerBehavior'),
  67:         ));
  68:     }
  69: 
  70:     protected function beforeAction($action = null) {
  71:         $this->validateMobileRequest ($action);
  72:         if (is_int(Yii::app()->locked) &&
  73:                 !Yii::app()->user->checkAccess('GeneralAdminSettingsTask') &&
  74:                 !(in_array($this->action->id, array('login', 'logout')) ||
  75:                 Yii::app()->user->isGuest)) {
  76: 
  77:             $this->appLockout();
  78:         }
  79:         return $this->runBehaviorBeforeActionHandlers ($action);
  80:     }
  81: 
  82:     public function accessRules() {
  83:         return array(
  84:             array('allow',
  85:                 'actions' => array(
  86:                     'login', 'forgetMe', 'index', 'logout', 'warning', 'captcha', 'googleLogin',
  87:                     'error', 'storeToken', 'sendErrorReport', 'resetPassword', 'anonHelp',
  88:                     'mobileResetPassword'),
  89:                 'users' => array('*'),
  90:             ),
  91:             array('allow', // allow authenticated user to perform 'create' and 'update' actions
  92:                 'actions' => array(
  93:                     'groupChat', 'newMessage', 'getMessages', 'checkNotifications', 'updateNotes',
  94:                     'addPersonalNote', 'getNotes', 'getURLs', 'addSite', 'deleteMessage',
  95:                     'fullscreen', 'widgetState', 'widgetOrder', 'saveGridviewSettings',
  96:                     'saveFormSettings', 'saveWidgetHeight', 'inlineEmail', 'tmpUpload', 'upload',
  97:                     'uploadProfilePicture', 'index', 'contact', 'viewNotifications', 'inlineEmail',
  98:                     'toggleShowTags', 'appendTag', 'removeTag', 'printRecord',
  99:                     'createRecords', 'toggleVisibility', 'page', 'showWidget', 'hideWidget',
 100:                     'reorderWidgets', 'minimizeWidget', 'publishPost', 'getEvents', 'loadComments',
 101:                     'loadPosts', 'addComment', 'flagPost', 'broadcastEvent', 'minimizePosts',
 102:                     'bugReport', 'deleteRelationship', 'minMaxLeftWidget', 'toggleFeedControls',
 103:                     'toggleFeedFilters', 'share', 'activityFeedOrder',
 104:                     'activityFeedWidgetBgColor', 'likePost', 'loadLikeHistory', 'dynamicDropdown',
 105:                     'stickyPost', 'getEventsBetween', 'mediaWidgetToggle', 'createChartSetting',
 106:                     'deleteChartSetting', 'GetActionsBetweenAction', 'DeleteURL', 'widgetSetting',
 107:                     'removeTmpUpload', 'duplicateCheck', 'resolveDuplicates', 'getSkypeLink',
 108:                     'mergeRecords', 'ajaxSave', 'layoutPreview','tourSeen'),
 109:                 'users' => array('@'),
 110:             ),
 111:             array('allow',
 112:                 'actions' => array('motd'),
 113:                 'users' => array('admin'),
 114:             ),
 115:             array('deny',
 116:                 'users' => array('*')
 117:             )
 118:         );
 119:     }
 120: 
 121:     public function actions() {
 122:         return array_merge ($this->getBehaviorActions (), array (
 123:             // captcha action renders the CAPTCHA image displayed on the contact page
 124:             'captcha' => array(
 125:                 'class' => 'CCaptchaAction',
 126:                 'backColor' => 0xFFFFFF,
 127:                 'testLimit' => 1,
 128:             ),
 129:             // page action renders "static" pages stored under 'protected/views/site/pages'
 130:             // They can be accessed via: index.php?r=site/page&view=FileName
 131:             'page' => array(
 132:                 'class' => 'CViewAction',
 133:             ),
 134:             'inlineEmail' => array(
 135:                 'class' => 'InlineEmailAction',
 136:             ),
 137:             'GetActionsBetweenAction' => array(
 138:                 'class' => 'GetActionsBetweenAction'
 139:             ),
 140:         ));
 141:     }
 142: 
 143: //    /**
 144: //     * Obtain the widget list for the current web user.
 145: //     *
 146: //     * @param CFilterChain $filterChain
 147: //     */
 148: //    public function filterSetPortletsq($filterChain){
 149: //        if(!Yii::app()->user->isGuest){
 150: //            $this->portlets=array();
 151: //            $this->portlets = Profile::getWidgets();
 152: //            // $this->portlets=array();
 153: //            // $arr=Profile::getWidgets(Yii::app()->user->getId());
 154: //
 155: //            // foreach($arr as $key=>$value){
 156: //                // $config=Profile::parseWidget($value,$key);
 157: //                // $this->portlets[$key]=$config;
 158: //            // }
 159: //        }
 160: //        $filterChain->run();
 161: //    }
 162: 
 163:     public function actionSendErrorReport() {
 164:         if (isset($_POST['report'])) {
 165:             $errorReport = $_POST['report'];
 166:             $errorReport = CJSON::decode(base64_decode($errorReport));
 167:             if (isset($_POST['email'])) {
 168:                 $errorReport['email'] = $_POST['email'];
 169:             }
 170:             if (isset($_POST['bugDescription'])) {
 171:                 $errorReport['bugDescription'] = $_POST['bugDescription'];
 172:             }
 173:             $errorReport['edition'] = Yii::app()->edition;
 174:             $errorReport = base64_encode(CJSON::encode($errorReport));
 175:             $ccUrl = "http://www.x2software.com/receiveErrorReport.php";
 176:             $ccSession = curl_init($ccUrl);
 177:             curl_setopt($ccSession, CURLOPT_POST, 1);
 178:             curl_setopt($ccSession, CURLOPT_HTTPHEADER, array('Accept-Charset: UTF-8;'));
 179:             curl_setopt($ccSession, CURLOPT_POSTFIELDS, array('errorReport' => $errorReport));
 180:             curl_setopt($ccSession, CURLOPT_RETURNTRANSFER, 1);
 181:             $ccResult = curl_exec($ccSession);
 182:             curl_close($ccSession);
 183:             echo $ccResult;
 184:         }
 185:     }
 186: 
 187:     public function actionActivityFeedOrder() {
 188:         $profile = Yii::app()->params->profile;
 189:         if (isset($profile)) {
 190:             $profile->activityFeedOrder = !$profile->activityFeedOrder;
 191:             $profile->update(array('activityFeedOrder'));
 192:         }
 193:     }
 194: 
 195:     public function actionActivityFeedWidgetBgColor($color) {
 196:         $profile = Yii::app()->params->profile;
 197:         if (isset($profile)) {
 198:             $theme = $profile->theme;
 199:             $theme['activityFeedWidgetBgColor'] = $color;
 200:             $profile->theme = $theme;
 201:             $profile->update(array('theme'));
 202:         }
 203:     }
 204: 
 205:     public function actionMediaWidgetToggle() {
 206:         $profile = Yii::app()->params->profile;
 207:         if (isset($profile)) {
 208:             $profile->mediaWidgetDrive = !$profile->mediaWidgetDrive;
 209:             $profile->update(array('mediaWidgetDrive'));
 210:         }
 211:     }
 212: 
 213:     /**
 214:      * Action to set a widget setting
 215:      * @param string $widget the widget name 
 216:      * @param string $setting the setting name
 217:      * @param string $value the value to save in the setting
 218:      * */
 219:     public function actionWidgetSetting($widget, $setting) {
 220:         $value = $_GET['value'];
 221:         Profile::changeWidgetSetting($widget, $setting, $value);
 222:     }
 223: 
 224:     // Outputs white or black depending on input color
 225:     // @param $colorString a string representing a hex number
 226:     // @param $testType standardText or linkText
 227:     function convertTextColor($colorString, $textType) {
 228:         // Split the string to red, green and blue components
 229:         // Convert hex strings into ints
 230:         $red = intval(substr($colorString, 0, 2), 16);
 231:         $green = intval(substr($colorString, 2, 2), 16);
 232:         $blue = intval(substr($colorString, 4, 2), 16);
 233:         if ($textType == 'standardText') {
 234:             return (((($red * 299) + ($green * 587) + ($blue * 114)) / 1000) >= 128) ? 'black' : 'white';
 235:         } else if ($textType == 'linkText') {
 236:             if (((($red < 100) || ($green < 100)) && $blue > 80) || (($red < 80) && ($green < 80) && ($blue < 80))) {
 237:                 return '#fff000';  // Yellow links
 238:             } else
 239:                 return '#0645AD'; // Blue link color
 240:         }
 241:         else if ($textType == 'visitedLinkText') {
 242:             if (((($red < 100) || ($green < 100)) && $blue > 80) || (($red < 80) && ($green < 80) && ($blue < 80))) {
 243:                 return '#ede100';  // Yellow links
 244:             } else
 245:                 return '#0B0080'; // Blue link color
 246:         }
 247:         else if ($textType == 'activeLinkText') {
 248:             if (((($red < 100) || ($green < 100)) && $blue > 80) || (($red < 80) && ($green < 80) && ($blue < 80))) {
 249:                 return '#fff000';  // Yellow links
 250:             } else
 251:                 return '#0645AD'; // Blue link color
 252:         }
 253:         else if ($textType == 'hoverLinkText') {
 254:             if (((($red < 100) || ($green < 100)) && $blue > 80) || (($red < 80) && ($green < 80) && ($blue < 80))) {
 255:                 return '#fff761';  // Yellow links
 256:             } else
 257:                 return '#3366BB'; // Blue link color
 258:         }
 259:     }
 260: 
 261:     public function actionDynamicDropdown($val, $dropdownId, $field = false, $module = null) {
 262:         $dropdown = X2Model::model('Dropdowns')->findByAttributes(array('parent' => $dropdownId, 'parentVal' => $val));
 263:         if (isset($dropdown)) {
 264:             if (!$field) {
 265:                 echo CHtml::tag('option', array('value' => ''), CHtml::encode('-'), true);
 266:                 $data = json_decode($dropdown->options, true);
 267:                 foreach ($data as $value => $name) {
 268:                     echo CHtml::tag('option', array('value' => $value), CHtml::encode($name), true);
 269:                 }
 270:             } else {
 271:                 $fieldRecord = X2Model::model('Fields')->findByAttributes(array('modelName' => $module, 'type' => 'dependentDropdown', 'linkType' => $dropdownId));
 272:                 if (isset($fieldRecord)) { // Look up dependentDropdown field with a link to the master dropdown.
 273:                     $htmlStr = CHtml::tag('option', array('value' => ''), CHtml::encode('Select an option'), true);
 274:                     $data = json_decode($dropdown->options, true);
 275:                     foreach ($data as $value => $name) { // Build an HTML string of the dropdown response.
 276:                         $htmlStr .= CHtml::tag('option', array('value' => $value), CHtml::encode($name), true);
 277:                     }
 278:                     echo CJSON::encode(array($fieldRecord->fieldName, $htmlStr)); // Echo back the field name to update + the dropdown HTMl.
 279:                 }
 280:             }
 281:         } else {
 282:             if (!$field) {
 283:                 echo CHtml::tag('option', array('value' => ''), '-', true);
 284:             } else {
 285:                 $fieldRecord = X2Model::model('Fields')->findByAttributes(array('modelName' => $module, 'type' => 'dependentDropdown', 'linkType' => $dropdownId));
 286:                 if (isset($fieldRecord))
 287:                     echo CJSON::encode(array($fieldRecord->fieldName, CHtml::tag('option', array('value' => ''), '-', true)));
 288:             }
 289:         }
 290:     }
 291: 
 292:     /**
 293:      * Saves left widget minimize setting to user's profile.
 294:      * @param string ('collapse' | 'expand')
 295:      * @param string The name of the widget. This should match the widget name defined
 296:      *  in the layout stored in the user's profile.
 297:      * @return string 'failure' if the setting could not be saved, 'success' otherwise
 298:      */
 299:     public function actionMinMaxLeftWidget($action, $widgetName) {
 300:         $profile = Yii::app()->params->profile;
 301:         if (isset($profile)) {
 302:             $layout = $profile->getLayout();
 303:             $minimize;
 304:             if ($action === 'expand') {
 305:                 $minimize = false;
 306:             } else if ($action === 'collapse') {
 307:                 $minimize = true;
 308:             } else {
 309:                 echo 'failure';
 310:                 return;
 311:             }
 312:             if (in_array($widgetName, array_keys($layout['left']))) {
 313:                 $layout['left'][$widgetName]['minimize'] = $minimize;
 314:                 Yii::app()->params->profile->layout = json_encode($layout);
 315:                 Yii::app()->params->profile->update(array('layout'));
 316:             }
 317:             echo 'success';
 318:             return;
 319:         }
 320:         echo 'failure';
 321:     }
 322: 
 323:     /**
 324:      * Displays message of the day.
 325:      */
 326:     public function actionMotd() {
 327:         if (isset($_POST['message'])) {
 328:             $motd = $_POST['message'];
 329:             $temp = Social::model()->findByAttributes(array('type' => 'motd'));
 330:             $temp->data = $motd;
 331:             if ($temp->update())
 332:                 echo $motd;
 333:             else
 334:                 echo "An error has occured.";
 335:         }else {
 336:             echo "An error has occured.";
 337:         }
 338:     }
 339: 
 340:     /**
 341:      * Renders the group chat.
 342:      */
 343:     public function actionGroupChat() {
 344:         $this->portlets = array();
 345:         $this->layout = '//layouts/column1';
 346:         //$portlets = $this->portlets;
 347:         // display full screen group chat
 348:         $this->render('groupChat');
 349:     }
 350: 
 351:     /**
 352:      * Creates a new chat message from the current web user.
 353:      */
 354:     public function actionNewMessage() {
 355:         if (isset($_POST['chat-message']) && $_POST['chat-message'] != '' && $_POST['chat-message'] != Yii::t('app', 'Enter text here...')) {
 356: 
 357:             $user = Yii::app()->user->getName();
 358:             $chat = new Social;
 359:             $chat->data = $_POST['chat-message'];
 360:             ;
 361:             $chat->user = $user;
 362:             $chat->visibility = 1;
 363:             $chat->timestamp = time();
 364:             $chat->type = 'chat';
 365: 
 366:             if ($chat->save()) {
 367:                 echo CJSON::encode(array(
 368:                     array(
 369:                         $chat->id,
 370:                         date('g:i:s A', $chat->timestamp),
 371:                         '<span class="my-username">' . $chat->user . '</span>',
 372:                         $this->convertUrls($chat->data)
 373:                     )
 374:                 ));
 375:             }
 376:         }
 377:     }
 378: 
 379:     /**
 380:      * Add a personal note to the list of notes for the current web user.
 381:      */
 382:     public function actionAddPersonalNote() {
 383:         if (isset($_POST['note-message']) && $_POST['note-message'] != '') {
 384:             $user = Yii::app()->user->getName();
 385:             $note = new Social;
 386:             $note->associationId = Yii::app()->user->getId();
 387:             $note->data = $_POST['note-message'];
 388:             ;
 389:             $note->user = $user;
 390:             $note->visibility = 1;
 391:             $note->timestamp = time();
 392:             $note->type = 'note';
 393: 
 394:             if ($note->save()) {
 395:                 echo "1";
 396:             }
 397:         }
 398:     }
 399: 
 400:     /**
 401:      * Adds a new URL
 402:      */
 403:     public function actionAddSite() {
 404:         if ((isset($_POST['url-title']) && isset($_POST['url-url'])) && ($_POST['url-title'] != '' && $_POST['url-url'] != '')) {
 405: 
 406:             $site = new URL;
 407:             $site->title = $_POST['url-title'];
 408:             $site->url = $_POST['url-url'];
 409:             $site->userid = Yii::app()->user->getId();
 410:             $site->timestamp = time();
 411:             if ($site->save()) {
 412:                 echo CJSON::encode(array(
 413:                     CHtml::link(
 414:                             $site->title, URL::prependProto($site->url), array('target' => '_blank')),
 415:                     CHtml::link(
 416:                             '', array('/site/DeleteURL', 'id' => $site->id), array(
 417:                         'title' => Yii::t('app', 'Delete Link'),
 418:                         'class' => 'delete-top-site-link fa fa-close',
 419:                         'target' => '_blank'
 420:                             )
 421:                     )
 422:                 ));
 423:             }
 424:         }
 425:     }
 426: 
 427:     /**
 428:      * Obtains notes for displaying within the notes widget.
 429:      * @param string $url The deletion URL for notes
 430:      */
 431:     public function actionGetNotes($url) {
 432:         $content = Social::model()->findAllByAttributes(array('type' => 'note', 'associationId' => Yii::app()->user->getId()), array(
 433:             'order' => 'timestamp DESC',
 434:         ));
 435:         $res = "";
 436:         foreach ($content as $item) {
 437:             $res .= $this->convertUrls(CHtml::encode($item->data)) . " " . CHtml::link('[x]', array('/site/deleteMessage', 'id' => $item->id, 'url' => $url)) . '<br /><br />';
 438:         }
 439:         if ($res == "") {
 440:             $res = Yii::t('app', "Feel free to enter some notes!");
 441:         }
 442:         echo $res;
 443:     }
 444: 
 445:     public function actionDeleteURL($id) {
 446:         if (isset($id)) {
 447:             Yii::app()->db->createCommand()->delete(
 448:                     'x2_urls', 'id=:id', array(':id' => $id));
 449:         }
 450:     }
 451: 
 452:     public function actionEditURL($id, $url) {
 453:         //$entry->title = 'ggg';
 454:         //$this->list = array('item1','item2');
 455:         $this->redirect($url);
 456:     }
 457: 
 458:     /**
 459:      * Gets URLs for "top sites"
 460:      * @param string $url
 461:      */
 462:     /* public function actionGetURLs($url){
 463:       $content = URL::model()->findAllByAttributes(
 464:       array('userid' => Yii::app()->user->getId()), array('order' => 'timestamp DESC'));
 465:       $res = '<table><tr><th>'.Yii::t('app', 'Link').'</th><th>Delete</th></tr>';
 466:       if($content){
 467:       foreach($content as $entry){
 468:       if(strpos($entry->url, 'http://') === false){
 469:       $entry->url = "http://".$entry->url;
 470:       }
 471:       $res .=
 472:       '<tr>'.
 473:       '<td>' .
 474:       CHtml::link(
 475:       Yii::t('app', $entry->title), $entry->url,
 476:       array('target'=>'_blank')) .
 477:       "</td>".
 478:       "<td>" .
 479:       CHtml::link(
 480:       'Delete',
 481:       array('/site/DeleteURL', 'id' => $entry->id, 'url' => $url)).
 482:       "</td>".
 483:       "</tr>";
 484:       }
 485:       }else{
 486:       $res .=
 487:       "<tr><td>".
 488:       CHtml::link(
 489:       Yii::t('app', 'Example'), 'http://www.x2engine.com',
 490:       array('target'=>'_blank')).
 491:       "</td><td>".
 492:       "<a href='.'>".Yii::t('app', 'Delete')."</a>".
 493:       "</td></tr>";
 494:       }
 495:       echo $res;
 496:       } */
 497: 
 498:     /**
 499:      * Delete a message from the social feed.
 500:      * @param integer $id
 501:      * @param string $url
 502:      */
 503:     public function actionDeleteMessage($id, $url) {
 504:         $note = Social::model()->findByPk($id);
 505:         if (isset($note))
 506:             $note->delete();
 507:         $this->redirect($url);
 508:     }
 509: 
 510:     /**
 511:      * Sets "Fullscreen" mode for the current web user / session
 512:      */
 513:     public function actionFullscreen() {
 514:         Yii::app()->session['fullscreen'] = (isset($_GET['fs']) && $_GET['fs'] == 1);
 515:         $profile = Yii::app()->params->profile;
 516:         $profile->fullscreen = (isset($_GET['fs']) && $_GET['fs'] == 1);
 517:         $profile->update(array('fullscreen'));
 518:         // echo var_dump(Yii::app()->session['fullscreen']);
 519:         echo 'Success';
 520:     }
 521: 
 522:     public function actionDeleteRelationship($firstId, $firstType, $secondId, $secondType) {
 523:         $rel = X2Model::model('Relationships')->findByAttributes(array('firstId' => $firstId, 'firstType' => $firstType, 'secondId' => $secondId, 'secondType' => $secondType));
 524:         if (isset($rel)) {
 525:             $rel->delete();
 526:         } else {
 527:             $rel = X2Model::model('Relationships')->findByAttributes(array('firstId' => $secondId, 'firstType' => $secondType, 'secondId' => $firstId, 'secondType' => $firstType));
 528:             if (isset($rel)) {
 529:                 $rel->delete();
 530:             }
 531:         }
 532:         if (isset($_GET['redirect'])) {
 533:             $this->redirect($this->createUrl($_GET['redirect']));
 534:         }
 535:     }
 536: 
 537:     /**
 538:      * Checks for the widget's state.
 539:      */
 540:     public function actionWidgetState() {
 541: 
 542:         if (isset($_GET['widget']) && isset($_GET['state'])) {
 543:             $widgetName = $_GET['widget'];
 544:             $widgetState = ($_GET['state'] == 0) ? '0' : '1';
 545: 
 546:             // $profile = Yii::app()->params->profile;
 547: 
 548:             $order = explode(":", Yii::app()->params->profile->widgetOrder);
 549:             $visibility = explode(":", Yii::app()->params->profile->widgets);
 550: 
 551:             // var_dump($order);
 552:             // var_dump($visibility);
 553:             if (array_key_exists($widgetName, Yii::app()->params->registeredWidgets)) {
 554: 
 555:                 $pos = array_search($widgetName, $order);
 556:                 $visibility[$pos] = $widgetState;
 557:                 // die(var_dump($visibility));
 558: 
 559:                 Yii::app()->params->profile->widgets = implode(':', $visibility);
 560: 
 561:                 if (Yii::app()->params->profile->update(array('widgets'))) {
 562:                     echo 'success';
 563:                 }
 564:             }
 565:         }
 566:     }
 567: 
 568:     /**
 569:      * Responds with the order of widgets for the current user.
 570:      */
 571:     public function actionWidgetOrder() {
 572:         if (isset($_POST['widget'])) {
 573: 
 574:             $widgetList = $_POST['widget'];
 575: 
 576:             // $profile = Yii::app()->params->profile;
 577:             $order = Yii::app()->params->profile->widgetOrder;
 578:             $visibility = Yii::app()->params->profile->widgets;
 579: 
 580:             $order = explode(":", $order);
 581:             $visibility = explode(":", $visibility);
 582: 
 583:             $newOrder = array();
 584: 
 585:             foreach ($widgetList as $item) {
 586:                 if (array_key_exists($item, Yii::app()->params->registeredWidgets))
 587:                     $newOrder[] = $item;
 588:             }
 589:             $str = "";
 590:             $visStr = "";
 591:             foreach ($newOrder as $item) {
 592:                 $pos = array_search($item, $order);
 593:                 $vis = $visibility[$pos];
 594:                 $str.=$item . ":";
 595:                 $visStr.=$vis . ":";
 596:             }
 597:             $str = substr($str, 0, -1);
 598:             $visStr = substr($visStr, 0, -1);
 599: 
 600:             Yii::app()->params->profile->widgetOrder = $str;
 601:             Yii::app()->params->profile->widgets = $visStr;
 602: 
 603:             if (Yii::app()->params->profile->save()) {
 604:                 echo 'success';
 605:             }
 606:         }
 607:     }
 608: 
 609:     /**
 610:      * Save custom gridview settings.
 611:      *
 612:      * Saves the settings (i.e. columns, column position and column width)
 613:      * for the X2GridView model.
 614:      */
 615:     public function actionSaveGridviewSettings() {
 616:         $result = false;
 617: 
 618:         // gv settings parameter is prefixed by a unique id
 619:         $gvSettings;
 620:         foreach ($_POST as $key => $val) {
 621:             if (preg_match("/gvSettings$/", $key)) {
 622:                 $gvSettings = json_decode($val, true);
 623:             }
 624:         }
 625: 
 626:         if (isset($gvSettings) && isset($_POST['viewName'])) {
 627:             if (isset($gvSettings))
 628:                 $result = Profile::setGridviewSettings($gvSettings, $_POST['viewName']);
 629:         }
 630:         if ($result)
 631:             echo '200 Success';
 632:         else
 633:             echo '400 Failure';
 634:     }
 635: 
 636:     /**
 637:      * Save settings for a custom form layout.
 638:      *
 639:      * @throws CHttpException
 640:      */
 641:     public function actionSaveFormSettings() {
 642:         $result = false;
 643:         if (isset($_GET['formSettings']) && isset($_GET['formName'])) {
 644:             $formSettings = json_decode($_GET['formSettings'], true);
 645: 
 646:             if (isset($formSettings))
 647:                 $result = Profile::setFormSettings($formSettings, $_GET['formName']);
 648:         }
 649:         if ($result)
 650:             echo 'success';
 651:         else
 652:             throw new CHttpException(400, 'Invalid request. Probabaly something wrong with the JSON string.');
 653:     }
 654: 
 655:     /**
 656:      * Saves the height of a widget.
 657:      */
 658:     public function actionSaveWidgetHeight() {
 659:         if (isset($_POST['Widget']) && isset($_POST['Height'])) {
 660:             $heights = $_POST['Height'];
 661:             $widget = $_POST['Widget'];
 662:             $widgetSettings = Profile::getWidgetSettings();
 663: 
 664:             foreach ($heights as $key => $height) {
 665:                 $widgetSettings->$widget->$key = intval($height);
 666:             }
 667: 
 668:             Yii::app()->params->profile->widgetSettings = json_encode($widgetSettings);
 669:             Yii::app()->params->profile->update();
 670:         }
 671:     }
 672: 
 673:     /**
 674:      * Uploads a file to a temporary folder.
 675:      *
 676:      * Upload a file to a temp folder, which will presumably be deleted shortly thereafter
 677:      * Temp files are stored in a temp folder with a randomly generated name. They are stored
 678:      * in 'uploads/media/temp'
 679:      */
 680:     public function actionTmpUpload() {
 681:         if (isset($_FILES['upload'])) {
 682:             $upload = CUploadedFile::getInstanceByName('upload');
 683: 
 684:             if ($upload) {
 685: 
 686:                 $name = $upload->getName();
 687:                 $name = str_replace(' ', '_', $name);
 688: 
 689:                 $temp = TempFile::createTempFile($name);
 690: 
 691:                 if ($temp && $upload->saveAs($temp->fullpath())) // temp file saved
 692:                     echo json_encode(array('status' => 'success', 'id' => $temp->id, 'name' => $name));
 693:                 else
 694:                     echo json_encode(array('status' => 'fail', 'message' => Yii::t('media', 'Failed to upload file.')));
 695:             } else {
 696:                 echo json_encode(array('status' => 'notsent', 'message' => Yii::t('media', 'File was not sent to server.')));
 697:             }
 698:         } else {
 699:             echo json_encode(array('status' => 'fail', 'message' => Yii::t('media', 'Failed to upload file.')));
 700:         }
 701:     }
 702: 
 703:     private function handleDefaultUpload($model, $name) {
 704:         $note = new Actions;
 705:         $note->createDate = time();
 706:         $note->dueDate = time();
 707:         $note->completeDate = time();
 708:         $note->complete = 'Yes';
 709:         $note->visibility = '1';
 710:         $note->completedBy = Yii::app()->user->getName();
 711:         if ($model->private) {
 712:             $note->assignedTo = Yii::app()->user->getName();
 713:             $note->visibility = '0';
 714:         } else {
 715:             $note->assignedTo = 'Anyone';
 716:         }
 717:         $note->type = 'attachment';
 718:         $note->associationId = $_POST['associationId'];
 719:         $note->associationType = $_POST['associationType'];
 720: 
 721:         $association = $this->getAssociation($note->associationType, $note->associationId);
 722:         if ($association != null)
 723:             $note->associationName = $association->name;
 724: 
 725:         $note->actionDescription = $model->fileName . ':' . $model->id;
 726:         if ($note->save()) {
 727:             
 728:         } else {
 729:             unlink('uploads/protected/' . $name);
 730:         }
 731:         if ($model->associationType == 'product')
 732:             $this->redirect(array('/products/products/view', 'id' => $model->associationId));
 733:         $this->redirect(array($model->associationType . '/' . $model->associationType . '/view', 'id' => $model->associationId));
 734:     }
 735: 
 736:     /**
 737:      * @param object $model
 738:      * @param string $name
 739:      */
 740:     private function handleFeedTypeUpload($model, $name) {
 741:         $event = new Events;
 742:         $event->user = Yii::app()->user->getName();
 743:         if (isset($_POST['attachmentText']) && !empty($_POST['attachmentText'])) {
 744:             $event->text = $_POST['attachmentText'];
 745:         } else {
 746:             $event->text = Yii::t('app', 'Attached file: ');
 747:         }
 748:         $event->type = 'media';
 749:         $event->timestamp = time();
 750:         $event->lastUpdated = time();
 751:         $event->associationId = $model->id;
 752:         $event->associationType = 'Media';
 753:         if ($event->save()) {
 754:             //$this->redirect('profile');
 755:         } else {
 756:             unlink('uploads/protected/' . $name);
 757:         }
 758: 
 759: 
 760:         if (isset($_POST['profileId'])) {
 761:             $this->redirect(array('/profile/view', 'id' => $_POST['profileId']));
 762:         } else {
 763:             $this->redirect(array('/profile/view', 'id' => Yii::app()->user->getId()));
 764:         }
 765: 
 766:     }
 767:     
 768:     private function handleTopicReplyUpload($model, $name){
 769:         $topicReply = new TopicReplies;
 770: 
 771:         if (isset ($_POST['TopicReplies'])) {
 772:             $topicReply->setAttributes ($_POST['TopicReplies']);
 773:             if($topicReply->save()){
 774:                 $model->associationId = $topicReply->id;
 775:                 $model->update(array('associationId'));
 776:                 echo $topicReply->id;
 777:             }else{
 778:                 file_exists ('uploads/protected/' . $name) && unlink('uploads/protected/' . $name);
 779:                 echo CJSON::encode (array (
 780:                     'message' => $topicReply->getAllErrorMessages (),
 781:                 ));
 782:             }
 783:         }else{
 784:             file_exists ('uploads/protected/' . $name) && unlink('uploads/protected/' . $name);
 785:             echo CJSON::encode (array (
 786:                 'message' => Yii::t('app', 'Reply '),
 787:             ));
 788:         }
 789:     }
 790: 
 791:     /**
 792:      * Remove a temp file and the temp folder that is in.
 793:      */
 794:     public function actionRemoveTmpUpload() {
 795:         if (isset($_POST['id'])) {
 796:             $id = $_POST['id'];
 797:             if (is_numeric($id)) {
 798:                 $tempFile = TempFile::model()->findByPk($id);
 799:                 if ($tempFile) {
 800:                     $folder = $tempFile->folder;
 801:                     $name = $tempFile->name;
 802:                     if (file_exists('uploads/protected/media/temp/' . $folder . '/' . $name))
 803:                         unlink('uploads/protected/media/temp/' . $folder . '/' . $name); // delete file
 804:                     if (file_exists('uploads/protected/media/temp/' . $folder))
 805:                         rmdir('uploads/protected/media/temp/' . $folder); // delete folder
 806:                     $tempFile->delete(); // delete database entry tracking temp file
 807:                 }
 808:             }
 809:         }
 810:     }
 811: 
 812:     /**
 813:      * Upload a file.
 814:      */
 815:     public function actionUpload() {
 816:         if (!isset($_FILES['upload'])) {
 817:             throw new CHttpException('400', 'Invalid request.');
 818:         }
 819: 
 820:         if (isset($_POST['drive']) && $_POST['drive']) { // google drive
 821:             $auth = new GoogleAuthenticator();
 822:             if ($auth->getAccessToken()) {
 823:                 $service = $auth->getDriveService();
 824:             }
 825:             $createdFile = null;
 826:             if (isset($service, $_SESSION['access_token'], $_FILES['upload'])) {
 827:                 try {
 828:                     $file = new Google_Service_Drive_DriveFile();
 829:                     $file->setTitle($_FILES['upload']['name']);
 830:                     $file->setDescription('Uploaded by X2Engine');
 831:                     $file->setMimeType($_FILES['upload']['type']);
 832: 
 833:                     if (empty($_FILES['upload']['tmp_name'])) {
 834:                         $err = false;
 835:                         switch ($_FILES['newfile']['error']) {
 836:                             case UPLOAD_ERR_INI_SIZE:
 837:                             case UPLOAD_ERR_FORM_SIZE:
 838:                                 $err .= 'File size exceeds limit of ' . get_max_upload() . ' bytes.';
 839:                                 break;
 840:                             case UPLOAD_ERR_PARTIAL:
 841:                                 $err .= 'File upload was not completed.';
 842:                                 break;
 843:                             case UPLOAD_ERR_NO_FILE:
 844:                                 $err .= 'Zero-length file uploaded.';
 845:                                 break;
 846:                             default:
 847:                                 $err .= 'Internal error ' . $_FILES['newfile']['error'];
 848:                                 break;
 849:                         }
 850:                         if ((bool) $message) {
 851:                             throw new CException($message);
 852:                         }
 853:                     }
 854:                     $data = file_get_contents($_FILES['upload']['tmp_name']);
 855:                     $createdFile = $service->files->insert($file, array(
 856:                         'data' => $data,
 857:                         'mimeType' => $_FILES['upload']['type'],
 858:                         'uploadType' => 'multipart',
 859:                     ));
 860:                     if ($createdFile instanceof Google_Service_Drive_DriveFile) {
 861:                         $model = new Media;
 862:                         $model->fileName = $createdFile['id'];
 863:                         $model->name = $createdFile['title'];
 864:                         if (isset($_POST['associationId']))
 865:                             $model->associationId = $_POST['associationId'];
 866:                         if (isset($_POST['associationType']))
 867:                             $model->associationType = $_POST['associationType'];
 868:                         if (isset($_POST['private']))
 869:                             $model->private = $_POST['private'];
 870:                         $model->uploadedBy = Yii::app()->user->getName();
 871:                         $model->mimetype = $createdFile['mimeType'];
 872:                         $model->filesize = $createdFile['fileSize'];
 873:                         $model->drive = 1;
 874:                         $model->save();
 875:                         if ($model->associationType == 'feed') {
 876:                             $event = new Events;
 877:                             $event->user = Yii::app()->user->getName();
 878:                             if (isset($_POST['attachmentText']) && !empty($_POST['attachmentText'])) {
 879:                                 $event->text = $_POST['attachmentText'];
 880:                             } else {
 881:                                 $event->text = Yii::t('app', 'Attached file: ');
 882:                             }
 883:                             $event->type = 'media';
 884:                             $event->timestamp = time();
 885:                             $event->lastUpdated = time();
 886:                             $event->associationId = $model->id;
 887:                             $event->associationType = 'Media';
 888:                             $event->save();
 889:                             if (Auxlib::isAjax()) return print("success");
 890:                             $this->redirect(array('/profile/view', 'id' => Yii::app()->user->getId()));
 891:                         } elseif ($model->associationType == 'docs') {
 892:                             if (Auxlib::isAjax()) return print("success");
 893:                             $this->redirect(array('/docs/docs/index'));
 894:                         } elseif (!empty($model->associationType) && !empty($model->associationId)) {
 895:                             $note = new Actions;
 896:                             $note->createDate = time();
 897:                             $note->dueDate = time();
 898:                             $note->completeDate = time();
 899:                             $note->complete = 'Yes';
 900:                             $note->visibility = '1';
 901:                             $note->completedBy = Yii::app()->user->getName();
 902:                             if ($model->private) {
 903:                                 $note->assignedTo = Yii::app()->user->getName();
 904:                                 $note->visibility = '0';
 905:                             } else {
 906:                                 $note->assignedTo = 'Anyone';
 907:                             }
 908:                             $note->type = 'attachment';
 909:                             $note->associationId = $_POST['associationId'];
 910:                             $note->associationType = $_POST['associationType'];
 911: 
 912:                             $association = $this->getAssociation($note->associationType, $note->associationId);
 913:                             if ($association != null)
 914:                                 $note->associationName = $association->name;
 915: 
 916:                             $note->actionDescription = $model->fileName . ':' . $model->id;
 917:                             if ($note->save()) {
 918:                                 if (Auxlib::isAjax()) return print("success");
 919:                                 $this->redirect(array($model->associationType . '/' . $model->associationId));
 920:                             }
 921:                         } else {
 922:                             if (Auxlib::isAjax()) return print("success");
 923:                             $this->redirect('/media/media/view', array('id' => $model->id));
 924:                         }
 925:                     } else {
 926:                         throw new CHttpException('400', 'Invalid request.');
 927:                     }
 928:                 } catch (Google_Auth_Exception $e) {
 929:                     $auth->flushCredentials();
 930:                     $auth->setErrors($e->getMessage());
 931:                     $service = null;
 932:                     $createdFile = null;
 933:                 }
 934:             } else {
 935:                 if (isset($_SERVER['HTTP_REFERER'])) {
 936:                     if (Auxlib::isAjax()) return print("success");
 937:                     $this->redirect($_SERVER['HTTP_REFERER']);
 938:                 } else {
 939:                     throw new CHttpException('400', 'Invalid request');
 940:                 }
 941:             }
 942:         } else { // non-google drive upload
 943:             $model = new Media;
 944:             $temp = CUploadedFile::getInstanceByName('upload'); // file uploaded through form
 945:             if ($temp && ($tempName = $temp->getTempName()) && !empty($tempName)) {
 946:                 $name = $temp->getName();
 947:                 $name = str_replace(' ', '_', $name);
 948:                 $model->fileName = $name;
 949:                 $model->resolveNameConflicts ();
 950: 
 951:                 $username = Yii::app()->user->name;
 952:                 // copy file to user's media uploads directory
 953:                 if (FileUtil::ccopy(
 954:                     $tempName, "uploads/protected/media/$username/$model->fileName")) {
 955: 
 956:                     if (isset($_POST['associationId']))
 957:                         $model->associationId = $_POST['associationId'];
 958:                     if (isset($_POST['associationType']))
 959:                         $model->associationType = $_POST['associationType'];
 960:                     if (isset($_POST['private']))
 961:                         $model->private = true;
 962:                     $model->uploadedBy = Yii::app()->user->getName();
 963:                     $model->createDate = time();
 964:                     $model->lastUpdated = time();
 965:                     $model->mimetype = $temp->type;
 966: 
 967:                     if (!$model->save()) {
 968:                         $errors = $model->getErrors ();
 969:                         $error = ArrayUtil::pop (ArrayUtil::pop ($errors));
 970:                         Yii::app()->user->setFlash(
 971:                             'top-error', Yii::t('app', 'Attachment failed. '.$error));
 972:                         if (Auxlib::isAjax()) return print("success");
 973:                         $this->redirect(
 974:                             array(
 975:                                 $model->associationType . '/' . $model->associationType . 
 976:                                     '/view', 
 977:                                 'id' => $model->associationId
 978:                             ));  
 979:                         Yii::app()->end ();
 980:                     } else {   
 981:                         $relatedModel = X2Model::getModelOfTypeWithId($model->associationType, $model->associationId, true);
 982:                         $model->createRelationship($relatedModel);
 983:                     }
 984: 
 985:                     // handle different upload types
 986:                     switch ($model->associationType) {
 987:                         case 'feed':
 988:                             $this->handleFeedTypeUpload($model, $name);
 989:                             break;
 990:                         case 'docs':
 991:                             if (Auxlib::isAjax()) return print("success");
 992:                             $this->redirect(array('/docs/docs/index'));
 993:                             break;
 994:                         case 'loginSound':
 995:                         case 'notificationSound':
 996:                             if (Auxlib::isAjax()) return print("success");
 997:                             $this->redirect(
 998:                                     array('/profile/settings', 'id' => Yii::app()->user->getId()));
 999:                             break;
1000:                         case 'bg':
1001:                         case 'bg-private':
1002:                             $this->redirect(
1003:                                 array(
1004:                                     '/profile/settings',
1005:                                     'bgId' => $model->id
1006:                                 )
1007:                             );
1008:                             break;
1009:                         case 'none':
1010:                             if (Auxlib::isAjax()) return print("success");
1011:                             break;
1012:                         case 'topicReply':
1013:                             $this->handleTopicReplyUpload($model, $name);
1014:                             break;
1015:                         default:
1016:                             $this->handleDefaultUpload($model, $name);
1017:                             break;
1018:                     }
1019:                 }
1020:             } else {
1021:                 if (isset($_SERVER['HTTP_REFERER'])) {
1022:                     if (Auxlib::isAjax()) return print("success");
1023:                     $this->redirect($_SERVER['HTTP_REFERER']);
1024:                 } else {
1025:                     throw new CHttpException('400', 'Invalid request');
1026:                 }
1027:             }
1028:             if (isset ($_GET['redirect'])) $this->redirect ($_SERVER['HTTP_REFERER']);
1029:         }
1030:     }
1031: 
1032:     public function actionUploadFeedPostPicture () {
1033:     }
1034: 
1035:     /**
1036:      * Upload contact profile picture from Facebook.
1037:      */
1038:     public function actionUploadProfilePicture() {
1039:         if (isset($_POST['photourl'])) {
1040:             $photourl = $_POST['photourl'];
1041:             $name = 'profile_picture_' . $_POST['associationId'] . '.jpg';
1042:             $model = new Media;
1043:             $check = Media::model()->findAllByAttributes(array('fileName' => $name));
1044:             if (count($check) != 0) {
1045:                 $count = 1;
1046:                 $newName = $name;
1047:                 $arr = explode('.', $name);
1048:                 $name = $arr[0];
1049:                 while (count($check) != 0) {
1050:                     $newName = $name . '(' . $count . ').jpg';
1051:                     $check = Media::model()->findAllByAttributes(array('fileName' => $newName));
1052:                     $count++;
1053:                 }
1054:                 $name = $newName;
1055:             }
1056:             $model->associationId = $_POST['associationId'];
1057:             $model->associationType = $_POST['type'];
1058:             $model->createDate = time();
1059:             $model->fileName = $name;
1060: 
1061:             // download and save picture
1062:             $img = FileUtil::ccopy($photourl, "uploads/protected/$name");
1063:             $model->save();
1064: 
1065:             // put picture into new action
1066:             $note = new Actions;
1067:             $note->createDate = time();
1068:             $note->dueDate = time();
1069:             $note->completeDate = time();
1070:             $note->complete = 'Yes';
1071:             $note->visibility = '1';
1072:             $note->completedBy = "Web Lead";
1073:             $note->assignedTo = 'Anyone';
1074:             $note->type = 'attachment';
1075:             $note->associationId = $_POST['associationId'];
1076:             $note->associationType = $_POST['type'];
1077: 
1078:             $association = $this->getAssociation($note->associationType, $note->associationId);
1079:             if ($association != null) {
1080:                 $note->associationName = $association->name;
1081:             }
1082:             $note->actionDescription = $model->fileName . ':' . $model->id;
1083:             if ($note->save()) {
1084:                 
1085:             } else {
1086:                 unlink('uploads/protected/' . $name);
1087:             }
1088:             $this->redirect(array($model->associationType . '/' . $model->associationId));
1089:         }
1090:     }
1091: 
1092:     /**
1093:      * Index action.
1094:      *
1095:      * This is the default 'index' action that is invoked when an action
1096:      * is not explicitly requested by users.
1097:      */
1098:     //
1099:     public function actionIndex() {
1100:         // renders the view file 'protected/views/site/index.php'
1101:         // using the default layout 'protected/views/layouts/main.php'
1102: 
1103:         if (Yii::app()->user->isGuest) {
1104:             $this->redirectToLogin ();
1105:         } else {
1106:             $profile = Yii::app()->params->profile;
1107:             if (Yii::app()->params->isAdmin) {
1108:                 $admin = &Yii::app()->settings;
1109:                 if (Yii::app()->session['versionCheck'] == false && $admin->updateInterval > -1 && ($admin->updateDate + $admin->updateInterval < time()))
1110:                     Yii::app()->session['alertUpdate'] = true;
1111:                 else
1112:                     Yii::app()->session['alertUpdate'] = false;
1113:             }else {
1114:                 Yii::app()->session['alertUpdate'] = false;
1115:             }
1116: 
1117:             if (empty($profile->startPage)) {
1118:                 $this->redirect(array('/profile/view', 'id' => Yii::app()->user->getId()));
1119:             } else {
1120:                 $controller = Yii::app()->file->set('protected/controllers/' . ucfirst($profile->startPage) . 'Controller.php');
1121:                 $module = Yii::app()->file->set('protected/modules/' . $profile->startPage . '/controllers/' . ucfirst($profile->startPage) . 'Controller.php');
1122:                 if ($controller->exists || $module->exists) {
1123:                     if ($controller->exists)
1124:                         $this->redirect(array($profile->startPage . '/index'));
1125:                     if ($module->exists)
1126:                         $this->redirect(array($profile->startPage . '/' . $profile->startPage . '/index'));
1127:                 } else {
1128:                     $page = CActiveRecord::model('Docs')->findByAttributes(array('name' => ucfirst($profile->startPage)));
1129:                     if (isset($page)) {
1130:                         $id = $page->id;
1131:                         $this->redirect(array('/docs/docs/view', 'id' => $id, 'static' => 'true'));
1132:                     } else {
1133:                         $this->redirect(array('/site/profile'));
1134:                     }
1135:                 }
1136:             }
1137:         }
1138:     }
1139: 
1140:     function phpinfo_array($return = false) {
1141:         ob_start();
1142:         phpinfo(-1);
1143: 
1144:         $pi = preg_replace(
1145:                 array('#^.*<body>(.*)</body>.*$#ms', '#<h2>PHP License</h2>.*$#ms',
1146:             '#<h1>Configuration</h1>#', "#\r?\n#", "#</(h1|h2|h3|tr)>#", '# +<#',
1147:             "#[ \t]+#", '#&nbsp;#', '#  +#', '# class=".*?"#', '%&#039;%',
1148:             '#<tr>(?:.*?)" src="(?:.*?)=(.*?)" alt="PHP Logo" /></a>'
1149:             . '<h1>PHP Version (.*?)</h1>(?:\n+?)</td></tr>#',
1150:             '#<h1><a href="(?:.*?)\?=(.*?)">PHP Credits</a></h1>#',
1151:             '#<tr>(?:.*?)" src="(?:.*?)=(.*?)"(?:.*?)Zend Engine (.*?),(?:.*?)</tr>#',
1152:             "# +#", '#<tr>#', '#</tr>#'), array('$1', '', '', '', '</$1>' . "\n", '<', ' ', ' ', ' ', '', ' ',
1153:             '<h2>PHP Configuration</h2>' . "\n" . '<tr><td>PHP Version</td><td>$2</td></tr>' .
1154:             "\n" . '<tr><td>PHP Egg</td><td>$1</td></tr>',
1155:             '<tr><td>PHP Credits Egg</td><td>$1</td></tr>',
1156:             '<tr><td>Zend Engine</td><td>$2</td></tr>' . "\n" .
1157:             '<tr><td>Zend Egg</td><td>$1</td></tr>', ' ', '%S%', '%E%'), ob_get_clean());
1158: 
1159:         $sections = explode('<h2>', strip_tags($pi, '<h2><th><td>'));
1160:         unset($sections[0]);
1161: 
1162:         $pi = array();
1163:         foreach ($sections as $section) {
1164:             $n = substr($section, 0, strpos($section, '</h2>'));
1165:             preg_match_all(
1166:                     '#%S%(?:<td>(.*?)</td>)?(?:<td>(.*?)</td>)?(?:<td>(.*?)</td>)?%E%#', $section, $askapache, PREG_SET_ORDER);
1167:             foreach ($askapache as $m)
1168:                 if (is_array($m) && count($m) == 4) {
1169:                     if (empty($p[$n]))
1170:                         $p[$n] = array();
1171:                     $pi[$n][$m[1]] = (!isset($m[3]) || $m[2] == $m[3]) ? $m[2] : array_slice($m, 2);
1172:                 }
1173:         }
1174: 
1175:         return ($return === false) ? print_r($pi) : $pi;
1176:     }
1177: 
1178:     /**
1179:      * Error printing.
1180:      *
1181:      * This is the action to handle external exceptions.
1182:      */
1183:     public function actionError() {
1184: 
1185:         function var_dump_to_string($var) {
1186:             $output = "<pre>";
1187:             _var_dump_to_string($var, $output);
1188:             $output .= "</pre>";
1189:             return $output;
1190:         }
1191: 
1192:         function _var_dump_to_string($var, &$output, $prefix = "") {
1193:             foreach ($var as $key => $value) {
1194:                 if (is_array($value)) {
1195:                     $output.= $prefix . $key . ": \n";
1196:                     _var_dump_to_string($value, $output, "  " . $prefix);
1197:                 } else {
1198:                     $output.= $prefix . $key . ": " . $value . "\n";
1199:                 }
1200:             }
1201:         }
1202: 
1203:         function is_disabled($function) {
1204:             $disabled_functions = explode(',', str_replace(" ", "", ini_get('disable_functions')));
1205:             return in_array($function, $disabled_functions);
1206:         }
1207: 
1208:         if ($error = Yii::app()->errorHandler->error) {
1209:             if ($this->isAjaxRequest ()) {
1210:                 echo $error['message'];
1211:             } else {
1212:                 $referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
1213:                 $userAgent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
1214:                 if ($error['code'] == '404') {
1215:                     $request = Yii::app()->request->requestUri;
1216:                     if (preg_match('/opportunity/', $request)) {
1217:                         $request = preg_replace('/opportunity/', 'opportunities', $request);
1218:                         $this->redirect($request);
1219:                     }
1220:                     if (empty($referer)) {
1221:                         $this->render('errorDisplay', $error);
1222:                         Yii::app()->end();
1223:                     }
1224:                 }
1225:                 if (in_array($error['code'], array('403', '400', '503'))) {
1226:                     $this->render('errorDisplay', $error);
1227:                     Yii::app()->end();
1228:                 }
1229:                 $request = Yii::app()->request->requestUri;
1230:                 if (!is_disabled('phpinfo')) {
1231:                     $info = $this->phpinfo_array(true);
1232:                 } else {
1233:                     $info = '';
1234:                 }
1235:                 if (!empty(Yii::app()->settings->emailFromAddr))
1236:                     $email = Yii::app()->settings->emailFromAddr;
1237:                 else
1238:                     $email = "";
1239:                 $get = var_dump_to_string($_GET);
1240:                 $post = var_dump_to_string($_POST);
1241:                 $phpversion = phpversion();
1242:                 $x2version = Yii::app()->params->version;
1243:                 unset($error['traces']);
1244:                 $error['trace'] = CHtml::encode($error['trace']);
1245:                 $phpInfoErrorReport = base64_encode(CJSON::encode(array_merge($error, array(
1246:                             'request' => $request,
1247:                             'phpinfo' => $info,
1248:                             'referer' => $referer,
1249:                             'get' => $get,
1250:                             'post' => $post,
1251:                             'phpversion' => $phpversion,
1252:                             'x2version' => $x2version,
1253:                             'adminEmail' => $email,
1254:                             'user' => Yii::app()->user->getName(),
1255:                             'isAdmin' => Yii::app()->params->isAdmin,
1256:                             'userAgent' => $userAgent,
1257:                 ))));
1258: 
1259:                 $errorReport = base64_encode(CJSON::encode(array_merge($error, array(
1260:                             'request' => $request,
1261:                             'referer' => $referer,
1262:                             'get' => $get,
1263:                             'post' => $post,
1264:                             'phpversion' => $phpversion,
1265:                             'x2version' => $x2version,
1266:                             'adminEmail' => $email,
1267:                             'user' => Yii::app()->user->getName(),
1268:                             'isAdmin' => Yii::app()->params->isAdmin,
1269:                             'userAgent' => $userAgent,
1270:                 ))));
1271: 
1272:                 $this->render('error', array_merge($error, array(
1273:                     'request' => $request,
1274:                     'info' => $info,
1275:                     'referer' => $referer,
1276:                     'get' => $get,
1277:                     'post' => $post,
1278:                     'phpversion' => $phpversion,
1279:                     'x2version' => $x2version,
1280:                     'errorReport' => $errorReport,
1281:                     'phpInfoErrorReport' => $phpInfoErrorReport,
1282:                 )));
1283:             }
1284:         }
1285:     }
1286: 
1287:     public function actionBugReport() {
1288: 
1289:         $info = $this->phpinfo_array(true);
1290:         if (!empty(Yii::app()->settings->emailFromAddr))
1291:             $email = Yii::app()->settings->emailFromAddr;
1292:         else
1293:             $email = "";
1294:         $phpversion = phpversion();
1295:         $x2version = Yii::app()->params->version;
1296:         $userAgent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
1297:         $phpInfoErrorReport = base64_encode(CJSON::encode(array(
1298:                     'phpinfo' => $info,
1299:                     'phpversion' => $phpversion,
1300:                     'x2version' => $x2version,
1301:                     'adminEmail' => $email,
1302:                     'user' => Yii::app()->user->getName(),
1303:                     'isAdmin' => Yii::app()->params->isAdmin,
1304:                     'userAgent' => $userAgent,
1305:         )));
1306: 
1307:         $errorReport = base64_encode(CJSON::encode(array(
1308:                     'phpversion' => $phpversion,
1309:                     'x2version' => $x2version,
1310:                     'adminEmail' => $email,
1311:                     'user' => Yii::app()->user->getName(),
1312:                     'isAdmin' => Yii::app()->params->isAdmin,
1313:                     'userAgent' => $userAgent,
1314:         )));
1315: 
1316:         $this->render('bugReport', array(
1317:             'phpInfoErrorReport' => $phpInfoErrorReport,
1318:             'errorReport' => $errorReport,
1319:             'x2version' => $x2version,
1320:             'phpversion' => $phpversion,
1321:         ));
1322:     }
1323: 
1324:     /**
1325:      *  Displays the About page
1326:      */
1327:     public function actionContact() {
1328:         $model = new ContactForm;
1329:         if (isset($_POST['ContactForm'])) {
1330:             $model->attributes = $_POST['ContactForm'];
1331:             if ($model->validate()) {
1332:                 $headers = "From: {$model->email}\r\nReply-To: {$model->email}";
1333:                 mail(Yii::app()->params['adminEmail'], $model->subject, $model->body, $headers);
1334:                 Yii::app()->user->setFlash('contact', 'Thank you for contacting us. We will respond to you as soon as possible.');
1335:                 $this->refresh();
1336:             }
1337:         }
1338:         $this->render('contact', array('model' => $model));
1339:     }
1340: 
1341:     /**
1342:      * Obtains the record association type for an object, i.e. contacts.
1343:      *
1344:      * @param string $type
1345:      * @param integer $id
1346:      * @return mixed
1347:      */
1348:     protected function getAssociation($type, $id) {
1349: 
1350:         $classes = array(
1351:             'actions' => 'Actions',
1352:             'contacts' => 'Contacts',
1353:             'accounts' => 'Accounts',
1354:             'product' => 'Product',
1355:             'products' => 'Product',
1356:             'Campaign' => 'Campaign',
1357:             'quote' => 'Quote',
1358:             'quotes' => 'Quote',
1359:             'opportunities' => 'Opportunity',
1360:         );
1361: 
1362:         if (array_key_exists($type, $classes) && $id != 0)
1363:             return X2Model::model($classes[$type])->findByPk($id);
1364:         else
1365:             return null;
1366:     }
1367: 
1368:     /**
1369:      * View all notifications for the current web user.
1370:      */
1371:     public function actionViewNotifications() {
1372:         $pageSize = Profile::getResultsPerPage();
1373: 
1374:         $dataProvider = new CActiveDataProvider('Notification', array(
1375:             'criteria' => array(
1376:                 // 'order'=>'viewed ASC',
1377:                 'condition' => 'user="' . Yii::app()->user->name . '"'
1378:             ),
1379:             'pagination' => array(
1380:                 'pageSize' => $pageSize,
1381:             ),
1382:             'sort' => array(
1383:                 'defaultOrder' => 'createDate DESC'
1384:             ),
1385:         ));
1386:         $this->render('viewNotifications', array(
1387:             'dataProvider' => $dataProvider,
1388:         ));
1389:     }
1390: 
1391:     public function actionWarning() {
1392:         header("Content-type: image/gif");
1393:         $img = 'R0lGODlhZABQAPcAANgAAP///w';
1394:         for ($i = 0; $i < 203; $i++)
1395:             $img .= 'AAAAA';
1396:         $img .= 'CwAAAAAZABQAAAI/wABCBxIsKDBgwgTKlzIsKHDhxAjSpxIsaLFixgzatzIsaPHjwkDiBS5cKRAkiBTKkQJIMBKlwNZqpxJUOZJkzdNjiS5s+VOnDph9qT5EqbPmzGNHk3acilSny6jClVK1CDQqUyzIpUKFaXMn1SrWuXq9CtVnmS9KrUptqBRtE+dLsUKd+7at23dDu2aFCdUpmrB+t2bt7Dhw4gTK57pV+viqmwfG7ZJ+GfOqYOHEn4cmaVnu1vTipYct+bbs5aPovWcWmPYiJ/jUg5bl29kjLcfxi6LNzZctWU3NpYItmvg04GNZ85NfDjptrWfiwUuHfrp6pDvTryKNaRzvWNdo//e3l33a9Mp2TL3HtqsWdPHMd+N/5KvXN0n0T9lfZC6ftCqnXdcafg1pZV/7vl3YHfR6bfXev01xh9vWSkoG4NkgXeZY+ZpCCCFAF63H12vsfYebMhxJ198mF024F/DJfgfdhlJGON5NDan12w54jabejj22FBnJQYpZFERIgShcS5eJ1VqKq5oZHhJVskQXgYaSFd+TWHpZUwQfXffjCGB2WVNSqLJ5ZdTUqnjlWbeeJaaWsa5JHxKijnmWJ8JSGeW8oHZJpnw4QihUGammSigay7qkJ6beahonWsiuuiXjXJ55aD1eZciUHLZ2GKTbeoZJqfY3bnpkZ4K5uqrrbHwWiistAom6624klchizC+aFlQtiKGKaVaWoqlpnNpiupHUfWXn3bEuuXgs5KV2BeazWYpraDFLpueVdiGa+xuZyLqLbPazilttseme6a2iQ1rKaVeXapmvcjmxd+v/Ga43GoBRprrwAQXbPDBCOMqZ6HXtvrkX/f1VNyfPDm60rbEzmukdl/RqTHG5XGqbrTKloRenxZnS/GkJnucL6MXc9tbyurtiHHLiY6r8sbicltps7SxPKixcRb98s1eamY0uM5arOjHMLfbdMlRL73WtE7zaSKeDecJrHIQR3m1oCMnjDPLZsdcZtpst+22QQEBADs=';
1397:         echo base64_decode($img);
1398:     }
1399: 
1400:     /**
1401:      * Clears remember me cookies and redirects to login page. 
1402:      */
1403:     public function actionForgetMe() {
1404:         $loginForm = new LoginForm;
1405:         foreach (array('username', 'rememberMe') as $attr) {
1406:             // Remove the cookie if they unchecked the box
1407: 
1408:             $cookieName = CHtml::resolveName($loginForm, $attr);
1409:             $cookie = new CHttpCookie(
1410:                 $cookieName, '');
1411:             $cookie->expire = time () - 3600; // expire cookie
1412:             Yii::app()->request->cookies[$cookieName] = $cookie;
1413:         }
1414:         $this->redirectToLogin ();
1415:     }
1416: 
1417:     /**
1418:      * Displays the login page
1419:      */
1420:     public function actionLogin() {
1421:         if (Yii::app()->isMobileApp ()) $this->redirect ('/mobile/login');
1422: 
1423:         
1424:         $model = new LoginForm;
1425:         $model->useCaptcha = false;
1426:         if ($this->loginRequiresCaptcha()) {
1427:             $model->useCaptcha = true;
1428:             $model->setScenario ('loginWithCaptcha');
1429:         }
1430: 
1431:         $profile = null;
1432:         if(isset($_COOKIE['LoginForm'])) {
1433:             $model->setAttributes($_COOKIE['LoginForm']);
1434:             if (is_array ($_COOKIE['LoginForm']) &&
1435:                 in_array ('username', array_keys ($_COOKIE['LoginForm']))) {
1436: 
1437:                 $username = $_COOKIE['LoginForm']['username'];
1438:                 $profile = Profile::model ()->findByAttributes (array (
1439:                     'username' => $username
1440:                 ));
1441:                 if ($profile) 
1442:                     Yii::app()->params->profile = $profile;
1443:             }
1444:         }
1445: 
1446:         $this->layout = '//layouts/login';
1447:         if (Yii::app()->user->isInitialized && !Yii::app()->user->isGuest) {
1448:             $this->redirect(Yii::app()->homeUrl);
1449:             return;
1450:         }
1451: 
1452: 
1453:         if (isset($_POST['LoginForm'])) {
1454:             $this->login($model);
1455:         }
1456: 
1457:         header('REQUIRES_AUTH: 1'); // tell windows making AJAX requests to redirect
1458: 
1459:         $this->render(
1460:             'login', 
1461:             array(
1462:                 'model' => $model,
1463:                 'profile' => $profile,
1464:             )
1465:         ); // display the login form
1466:     }
1467: 
1468:     /**
1469:      * Log in using a Google account.
1470:      */
1471:     public function actionGoogleLogin() {
1472:         $this->layout = '//layouts/login';
1473:         $model = new LoginForm;
1474:         $model->useCaptcha = false;
1475: 
1476:         // echo var_dump(Session::getOnlineUsers());
1477:         if (Yii::app()->user->isInitialized && !Yii::app()->user->isGuest) {
1478:             $this->redirect(Yii::app()->homeUrl);
1479:             return;
1480:         }
1481:         require_once 'protected/components/GoogleAuthenticator.php';
1482:         $auth = new GoogleAuthenticator();
1483: 
1484:         $credentials = Yii::app()->settings->getGoogleIntegrationCredentials ();
1485:         if ($credentials && Yii::app()->settings->googleIntegration && 
1486:             $token = $auth->getAccessToken()) {
1487: 
1488:             try {
1489:                 $user = $auth->getUserInfo($token);
1490:                 $email = filter_var($user->email, FILTER_SANITIZE_EMAIL);
1491:                 $profileRecord = X2Model::model('Profile')->findByAttributes(array('googleId' => $email));
1492:                 if (!isset($profileRecord)) {
1493:                     $userRecord = X2Model::model('User')->findByAttributes(array('emailAddress' => $email));
1494:                     $profileRecord = X2Model::model('Profile')->findByAttributes(array(), "emailAddress=:email OR googleId=:email", array(':email' => $email));
1495:                 }
1496:                 if (isset($userRecord) || isset($profileRecord)) {
1497:                     if (!isset($profileRecord)) {
1498:                         $profileRecord = X2Model::model('Profile')->findByPk($userRecord->id);
1499:                     }
1500:                     $auth->storeCredentials($profileRecord->id, $_SESSION['access_token']);
1501:                 }
1502:                 if (isset($userRecord) || isset($profileRecord)) {
1503:                     if (!isset($userRecord)) {
1504:                         $userRecord = User::model()->findByPk($profileRecord->id);
1505:                     }
1506:                     $username = $userRecord->username;
1507:                     $password = $userRecord->password;
1508:                     $model->username = $username;
1509:                     $model->password = $password;
1510:                     if ($model->login(true)) {
1511:                         $ip = $this->getRealIp();
1512: 
1513:                         Session::cleanUpSessions();
1514:                         if (isset($_SESSION['sessionId']))
1515:                             $sessionId = $_SESSION['sessionId'];
1516:                         else
1517:                             $sessionId = $_SESSION['sessionId'] = session_id();
1518: 
1519:                         $session = X2Model::model('Session')->findByPk($sessionId);
1520: 
1521:                         // if this client has already tried to log in, increment their attempt count
1522:                         if ($session === null) {
1523:                             $session = new Session;
1524:                             $session->id = $sessionId;
1525:                             $session->user = $model->getSessionUsername();
1526:                             $session->lastUpdated = time();
1527:                             $session->status = 1;
1528:                             $session->IP = $ip;
1529:                         } else {
1530:                             $session->lastUpdated = time();
1531:                         }
1532:                         // x2base::cleanUpSessions();
1533:                         // $session = X2Model::model('Session')->findByAttributes(array('user'=>$userRecord->username,'IP'=>$ip));
1534:                         // if(isset($session)) {
1535:                         // $session->lastUpdated = time();
1536:                         // } else {
1537:                         // $session = new Session;
1538:                         // $session->user = $model->username;
1539:                         // $session->lastUpdated = time();
1540:                         // $session->status = 1;
1541:                         // $session->IP = $ip;
1542:                         // }
1543:                         $session->save();
1544:                         SessionLog::logSession($userRecord->username, $sessionId, 'googleLogin');
1545:                         $userRecord->login = time();
1546:                         $userRecord->save();
1547:                         Yii::app()->session['versionCheck'] = true;
1548: 
1549:                         Yii::app()->session['loginTime'] = time();
1550:                         $session->status = 1;
1551: 
1552:                         if (Yii::app()->user->returnUrl == 'site/index')
1553:                             $this->redirect(array('/site/index'));
1554:                         else
1555:                             $this->redirect(Yii::app()->user->returnUrl);
1556:                     }
1557:                 }else {
1558:                     $this->render('googleLogin', array(
1559:                         'failure' => 'email',
1560:                         'email' => $email,
1561:                         'credentials' => $credentials,
1562:                     ));
1563:                 }
1564:             } catch (Google_Auth_Exception $e) {
1565:                 $auth->flushCredentials();
1566:                 $auth->setErrors($e->getMessage());
1567:                 $this->render('googleLogin', array(
1568:                     'failure' => $auth->getErrors(),
1569:                     'credentials' => $credentials,
1570:                 ));
1571:             } catch (NoUserIdException $e) {
1572:                 $auth->flushCredentials();
1573:                 $auth->setErrors($e->getMessage());
1574:                 $this->render('googleLogin', array(
1575:                     'failure' => $auth->getErrors(),
1576:                     'credentials' => $credentials,
1577:                 ));
1578:             }
1579:         } else {
1580:             $this->render('googleLogin');
1581:         }
1582:     }
1583: 
1584:     public function actionStoreToken() {
1585:         if(isset($_POST['code'])){
1586:             $code = $_POST['code'];
1587: 
1588:             require_once 'protected/integration/Google/google-api-php-client/src/Google/autoload.php';
1589: 
1590:             $client = new Google_Client();
1591:             $credentials = Yii::app()->settings->getGoogleIntegrationCredentials ();
1592:             $client->setClientId($credentials['clientId']);
1593:             $client->setClientSecret($credentials['clientSecret']);
1594:             $client->setRedirectUri('postmessage');
1595:             $client->setAccessType('offline');
1596:             $client->authenticate($code);
1597:             $token = json_decode($client->getAccessToken());
1598:             // Verify the token
1599:             $reqUrl = 'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=' .
1600:                     $token->access_token;
1601:             $req = new Google_Http_Request($reqUrl);
1602: 
1603:             $tokenInfo = json_decode(
1604:                     $client->getAuth()->authenticatedRequest($req)->getResponseBody());
1605:             // If there was an error in the token info, abort.
1606:             if (isset($tokenInfo->error) && $tokenInfo->error) {
1607:                 return new Response($tokenInfo->error, 500);
1608:             }
1609:             // Make sure the token we got is for our app.
1610:             if ($tokenInfo->audience != $credentials['clientId']) {
1611:                 return new Response(
1612:                         "Token's client ID does not match app's.", 401);
1613:             }
1614: 
1615:             // Store the token in the session for later use.
1616:             $_SESSION['token'] = json_encode($token);
1617:             $_SESSION['access_token'] = json_encode($token);
1618:             $auth = new GoogleAuthenticator();
1619:             $user = $auth->getUserInfo($client->getAccessToken());
1620:             $email = filter_var($user->email, FILTER_SANITIZE_EMAIL);
1621:             $profileRecord = Profile::model()->findByAttributes(array(), "emailAddress=:email OR googleId=:email", array(':email' => $email));
1622:             if (isset($profileRecord)) {
1623:                 $auth->storeCredentials($profileRecord->id, $_SESSION['access_token']);
1624:             }
1625:             $response = 'Successfully connected with token: ' . print_r($token, true);
1626:         }else{
1627:             $response = 'Invalid request.';
1628:         }
1629:         echo $response;
1630:     }
1631: 
1632:     /**
1633:      * Toggle display of tags.
1634:      */
1635:     public function actionToggleShowTags($tags) {
1636:         if ($tags == 'allUsers') {
1637:             Yii::app()->params->profile->tagsShowAllUsers = true;
1638:             Yii::app()->params->profile->update(array('tagsShowAllUsers'));
1639:         } else if ($tags == 'justMe') {
1640:             Yii::app()->params->profile->tagsShowAllUsers = false;
1641:             Yii::app()->params->profile->update(array('tagsShowAllUsers'));
1642:         }
1643:     }
1644: 
1645:     /**
1646:      * Adds a tag to a model.
1647:      *
1648:      * Echoes "true" if tag was created (and was not a duplicate), "false" otherwise.
1649:      */
1650:     public function actionAppendTag() {
1651:         if (isset($_POST['Type'], $_POST['Id'], $_POST['Tag']) &&
1652:                 preg_match('/^[\w\d_-]+$/', $_POST['Type'])) {
1653: 
1654:             if (!class_exists($_POST['Type'])) {
1655:                 echo 'false';
1656:                 return;
1657:             }
1658:             $model = X2Model::model($_POST['Type'])->findByPk($_POST['Id']);
1659: 
1660:             if ($model === null || !Yii::app()->controller->checkPermissions ($model, 'view')) {
1661:                 $this->denied ();
1662:             }
1663:             echo $model->addTags($_POST['Tag']);
1664:             Yii::app()->end ();
1665:         }
1666:         echo 'false';
1667:     }
1668: 
1669:     /**
1670:      * Removes a tag from a model.
1671:      *
1672:      * Echoes "true" if tag was removed, "false" otherwise.
1673:      */
1674:     public function actionRemoveTag() {
1675:         if (isset($_POST['Type'], $_POST['Id'], $_POST['Tag']) &&
1676:                 preg_match('/^[\w\d_-]+$/', $_POST['Type'])) {
1677: 
1678:             if (!class_exists($_POST['Type'])) {
1679:                 echo 'false';
1680:                 return;
1681:             }
1682:             $model = X2Model::model($_POST['Type'])->findByPk($_POST['Id']);
1683:             if ($model !== null && $model->removeTags($_POST['Tag'])) {
1684:                 echo 'true';
1685:                 return;
1686:             }
1687:         }
1688:         echo 'false';
1689:     }
1690: 
1691:     /**
1692:      * Display a print-friendly version of the x2layout view associated with the specified
1693:      * model class and id.
1694:      */
1695:     public function actionPrintRecord($modelClass, $id, $pageTitle = '') {
1696:         $this->layout = '//layouts/print';
1697: 
1698:         $modelTitle = '';
1699:         if (preg_match('/: /', $pageTitle)) {
1700:             $modelTitle = preg_replace('/(^.*):\ .*/', '\1', $pageTitle);
1701:             $pageTitle = preg_replace('/^.*:\ /', '', $pageTitle);
1702:         }
1703:         if (isset($id) && isset($modelClass)) {
1704:             //$model = $this->getModel ($id, true, $modelClass);
1705:             $model = CActiveRecord::model($modelClass)->findByPk((int) $id);
1706:             echo $this->render('printableRecord', array(
1707:                 'model' => $model,
1708:                 'modelClass' => $modelClass,
1709:                 'id' => $id,
1710:                 'pageTitle' => $pageTitle,
1711:                 'modelTitle' => $modelTitle
1712:                     ), true);
1713:             return;
1714:         }
1715:     }
1716: 
1717:     public function actionCreateRecords() {
1718:         $contact = new Contacts;
1719:         $account = new Accounts;
1720:         $opportunity = new Opportunity;
1721:         $users = User::getNames();
1722: 
1723:         if (isset($_POST['Contacts']) && isset($_POST['Accounts']) && isset($_POST['Opportunity'])) {
1724:             $contact->setX2Fields($_POST['Contacts']);
1725:             $account->setX2Fields($_POST['Accounts']);
1726:             $opportunity->setX2Fields($_POST['Opportunity']);
1727: 
1728:             $validAccount = true;
1729: 
1730:             if ($account->validate() == false) {
1731:                 $validAccount = false;
1732:                 // validate other models so that the user gets feedback
1733:                 $contact->validate();
1734:                 $opportunity->validate();
1735:             }
1736: 
1737:             if ($validAccount) {
1738:                 $allValid = true;
1739:                 $a = $this->createAccount($account, $account->attributes, '1');
1740: 
1741:                 // Contact and Opportunity require Account id for lookup field
1742:                 $contact->company = Fields::nameId($account->name, $account->id);
1743:                 if ($contact->validate() == false)
1744:                     $allValid = false;
1745:                 $c = $this->createContact($contact, $contact->attributes, '1');
1746: 
1747:                 $opportunity->accountName = Fields::nameId($account->name, $account->id);
1748:                 $opportunity->contactName = Fields::nameId($contact->name, $contact->id);
1749:                 if ($opportunity->validate() == false)
1750:                     $allValid = false;
1751:                 $o = $this->createOpportunity($opportunity, $opportunity->attributes, '1');
1752: 
1753:                 if ($allValid && $c && $a && $o) { // all records created?
1754:                     $contact->createRelationship($account);
1755:                     $opportunity->createRelationship($contact);
1756:                     $opportunity->createRelationship($account);
1757: 
1758:                     if (isset($_GET['ret'])) {
1759:                         if ($_GET['ret'] == 'contacts') {
1760:                             $this->redirect(array(
1761:                                 "/contacts/contacts/view",
1762:                                 'id' => $contact->id
1763:                             ));
1764:                         } else if ($_GET['ret'] == 'accounts') {
1765:                             $this->redirect(array(
1766:                                 "/accounts/accounts/view",
1767:                                 'id' => $account->id
1768:                             ));
1769:                         } else if ($_GET['ret'] == 'opportunities') {
1770:                             $this->redirect(array(
1771:                                 "/opportunities/opportunities/view",
1772:                                 'id' => $opportunity->id
1773:                             ));
1774:                         }
1775:                     } else {
1776:                         $this->redirect(array(
1777:                             "/contacts/contacts/view",
1778:                             $contact->id
1779:                         ));
1780:                     }
1781:                 } else {
1782:                     // otherwise clean up
1783:                     $types = array(
1784:                         'account' => 'Accounts',
1785:                         'contact' => 'Contacts',
1786:                         'opportunity' => 'Opportunity',
1787:                     );
1788:                     foreach ($types as $model => $type) {
1789:                         if (${$model} && isset(${$model}->id)) {
1790:                             $modelId = ${$model}->id;
1791:                             ${$model}->delete();
1792: 
1793:                             // delete all new actions and events from creating/deleting records
1794:                             foreach (array('Actions', 'Events') as $meta) {
1795:                                 X2Model::model($meta)->deleteAllByAttributes(array(
1796:                                     'associationId' => $modelId,
1797:                                     'associationType' => $type,
1798:                                 ));
1799:                             }
1800:                         }
1801:                     }
1802:                 }
1803:             }
1804:         }
1805: 
1806:         $this->render('createRecords', array(
1807:             'contact' => $contact,
1808:             'account' => $account,
1809:             'opportunity' => $opportunity,
1810:             'users' => $users,
1811:         ));
1812:     }
1813: 
1814:     /**
1815:      * Creates contact record
1816:      *
1817:      * Call this function from createRecords
1818:      */
1819:     public function createContact($model, $oldAttributes, $api) {
1820:         $model->createDate = time();
1821:         $model->lastUpdated = time();
1822:         if (empty($model->visibility) && $model->visibility != 0)
1823:             $model->visibility = 1;
1824:         if ($api == 0) {
1825:             parent::create($model, $oldAttributes, $api);
1826:         } else {
1827:             $lookupFields = Fields::model()->findAllByAttributes(array('modelName' => 'Contacts', 'type' => 'link'));
1828:             foreach ($lookupFields as $field) {
1829:                 $fieldName = $field->fieldName;
1830:                 if (isset($model->$fieldName)) {
1831:                     $lookup = X2Model::model(ucfirst($field->linkType))->findByAttributes(array('name' => $model->$fieldName));
1832:                     if (isset($lookup))
1833:                         $model->$fieldName = $lookup->id;
1834:                 }
1835:             }
1836:             return parent::create($model, $oldAttributes, $api);
1837:         }
1838:     }
1839: 
1840:     /**
1841:      * Creates account record
1842:      *
1843:      * Call this function from createRecords
1844:      */
1845:     public function createAccount($model, $oldAttributes, $api) {
1846: 
1847:         $model->annualRevenue = Formatter::parseCurrency($model->annualRevenue, false);
1848:         $model->createDate = time();
1849:         if ($api == 0)
1850:             parent::create($model, $oldAttributes, $api);
1851:         else
1852:             return parent::create($model, $oldAttributes, $api);
1853:     }
1854: 
1855:     /**
1856:      * Creates opportunity record
1857:      *
1858:      * Call this function from createRecords
1859:      */
1860:     public function createOpportunity($model, $oldAttributes, $api = 0) {
1861: 
1862:         // process currency into an INT
1863: //        $model->quoteAmount = Formatter::parseCurrency($model->quoteAmount,false);
1864: 
1865:         if (isset($model->associatedContacts))
1866:             $model->associatedContacts = Opportunity::parseContacts($model->associatedContacts);
1867:         $model->createDate = time();
1868:         $model->lastUpdated = time();
1869:         // $model->expectedCloseDate = Formatter::parseDate($model->expectedCloseDate);
1870:         if ($api == 1) {
1871:             return parent::create($model, $oldAttributes, $api);
1872:         } else {
1873:             parent::create($model, $oldAttributes, '0');
1874:         }
1875:     }
1876: 
1877:     /**
1878:      * Checks for any tasks that need to be executed at a specific time
1879:      *
1880:      * Needs to be called by a cronjob.
1881:      */
1882:     // public function actionCron() {
1883:     // $emails = X2Model::model('Actions')->findByAttributes(array(
1884:     // 'type'=>'email_staged',
1885:     // 'dueDate'=>'<'.time(),
1886:     // 'complete'=>'No'
1887:     // ));
1888:     // }
1889: 
1890:     /**
1891:      * Logs out the current user and redirect to homepage.
1892:      */
1893:     public function actionLogout() {
1894:         $user = User::model()->findByPk(Yii::app()->user->getId());
1895:         if (isset($user)) {
1896:             $user->lastLogin = time();
1897:             $user->save();
1898: 
1899:             if (isset($_SESSION['sessionId'])) {
1900:                 SessionLog::logSession($user->username, $_SESSION['sessionId'], 'logout');
1901:                 X2Model::model('Session')->deleteByPk($_SESSION['sessionId']);
1902:             } else {
1903:                 X2Model::model('Session')->deleteAllByAttributes(array('IP' => $this->getRealIp()));
1904:             }
1905:         }
1906:         if (isset($_SESSION['access_token']))
1907:             unset($_SESSION['access_token']);
1908: 
1909:         /* $login = new LoginForm;
1910:           foreach(array('username', 'rememberMe') as $attr){
1911:           // Remove the cookie if they unchecked the box
1912:           AuxLib::clearCookie(CHtml::resolveName($login, $attr));
1913:           } */
1914: 
1915:         Yii::app()->user->logout();
1916: 
1917:         $this->redirect(Yii::app()->homeUrl);
1918:     }
1919: 
1920:     public function actionToggleVisibility() {
1921:         $id = $_SESSION['sessionId'];
1922:         $session = Session::model()->findByAttributes(array('id' => $id));
1923:         if (isset($session)) {
1924:             if ($session->status < 0)
1925:                 $session->status = 0;
1926:             $session->status = !$session->status;
1927:             $session->save();
1928:             SessionLog::logSession(Yii::app()->user->getName(), $id, $session->status ? "visible" : "invisible");
1929:         }
1930:         $this->redirect($_GET['redirect']);
1931:     }
1932: 
1933:     /**
1934:      *  Remove a right widget from the page and put it in the hidden widgets menu
1935:      */
1936:     public function actionHideWidget() {
1937:         if (isset($_POST['name']) && isset ($_POST['position'])) {
1938:             $name = $_POST['name'];
1939:             $position = $_POST['position'];
1940: 
1941:             $layout = Yii::app()->params->profile->getLayout();
1942:             if (isset ($layout[$position][$name])) {
1943: 
1944:                 $layout['hiddenRight'][$name] = $layout[$position][$name];
1945:                 unset ($layout[$position][$name]);
1946:                 Yii::app()->params->profile->saveLayout($layout);
1947:             }
1948: 
1949:             echo Yii::app()->params->profile->getWidgetMenu();
1950:         }
1951:     }
1952: 
1953:     public function actionShowWidget() {
1954:         if (isset($_POST['name']) && isset($_POST['block'])) { // ensure we have the params we need
1955:             $name = $_POST['name'];
1956:             $block = $_POST['block'];
1957: 
1958:             if (isset($_POST['moduleName'])) {
1959:                 $moduleName = $_POST['moduleName'];
1960:             } else {
1961:                 $moduleName = '';
1962:             }
1963: 
1964:             if (isset($_POST['modelType']) && isset($_POST['modelId'])) {
1965:                 $modelType = $_POST['modelType'];
1966:                 $modelId = $_POST['modelId'];
1967:             }
1968: 
1969:             $layout = Yii::app()->params->profile->getLayout();
1970: 
1971:             if ($block == 'right') { // x2temp: remove when $layout['hiddenRight'] is merged into $layout['hidden']
1972:                 foreach ($layout['hiddenRight'] as $key => $widget) {
1973:                     if ($key == $name) {
1974:                         $widget['minimize'] = false; // un-minimize widgets when we show them
1975:                         $layout[$block][$key] = $widget;
1976:                         unset($layout['hiddenRight'][$key]);
1977:                         Yii::app()->params->profile->saveLayout($layout);
1978:                         Yii::app()->session['fullscreen'] = false; // we just added a widget to the right sidebar, so turn off fullscreen mode
1979:                         //    Yii::app()->clientScript->scriptMap['*.js'] = false;
1980:                         //    $this->renderPartial('application.components.views.centerWidget', array('widget'=>$widget, 'name'=>$name, 'modelType'=>$modelType, 'modelId'=>$modelId), false, true);
1981: 
1982:                         break;
1983:                     }
1984:                 }
1985:             }
1986:         }
1987:     }
1988: 
1989:     public function actionReorderWidgets() {
1990:         if (isset($_POST['x2widget']) && isset($_POST['x2widget'])) {
1991:             $widgets = $_POST['x2widget']; // list of widgets
1992:             $block = $_POST['block']; // left, right, or center
1993:             $layout = Yii::app()->params->profile->getLayout();
1994: 
1995:             if ($block === 'left') {
1996: 
1997:                 $newOrder = array();
1998: 
1999:                 // remove ordered left widgets from the layout and prepend them to the list
2000:                 // of left widgets in the new order
2001:                 foreach ($widgets as $name) {
2002:                     foreach ($layout[$block] as $key => $widget) {
2003:                         if ($key == $name) {
2004:                             $newOrder[$key] = $widget;
2005:                             unset($layout[$block][$key]);
2006:                         }
2007:                     }
2008:                 }
2009:                 $layout[$block] = $newOrder + $layout[$block];
2010:             } else {
2011:                 $newOrder = array();
2012: 
2013:                 foreach ($widgets as $name) {
2014:                     foreach ($layout[$block] as $key => $widget) {
2015:                         if ($key == $name) {
2016:                             $newOrder[$key] = $widget;
2017:                         }
2018:                     }
2019:                 }
2020: 
2021:                 $layout[$block] = $newOrder;
2022:                 Yii::app()->params->profile->saveLayout($layout);
2023:             }
2024:             Yii::app()->params->profile->saveLayout($layout);
2025:         }
2026:     }
2027: 
2028:     function actionMinimizeWidget() {
2029:         if (isset($_POST['name']) && isset($_POST['minimize'])) {
2030:             $name = $_POST['name'];
2031:             $minimize = json_decode($_POST['minimize']);
2032:             $layout = Yii::app()->params->profile->getLayout();
2033: 
2034:             // the widget could be in any of the blocks in the page, so check all of them
2035:             foreach ($layout as &$block) {
2036:                 foreach ($block as $key => &$widget) {
2037:                     if ($key == $name) {
2038:                         $widget['minimize'] = $minimize;
2039:                         Yii::app()->params->profile->saveLayout($layout);
2040:                         break 2;
2041:                     }
2042:                 }
2043:             }
2044:         }
2045:     }
2046: 
2047:     public function resetPasswordHelper ($id, $title) {
2048:         $scenario = 'new';
2049:         $message = Yii::t('app', 'Enter the email address associated with your user account to request a new password and username reminder.');
2050:         $request = new PasswordReset;
2051:         $resetForm = null;
2052: 
2053:         if (isset($_POST['PasswordReset'])) {
2054:             // Submitting a password reset request
2055:             $request->setAttributes($_POST['PasswordReset']);
2056:             if ($request->save()) {
2057:                 $request->setScenario('afterSave');
2058:                 if (!$request->validate(array('email'))) {
2059:                     // Create a new model. It is done this way (adding the
2060:                     // validation error to a new model) so that there is a trail
2061:                     // of reset request attempts that can be counted to determine
2062:                     // if the user has made too many.
2063:                     $oldRequest = $request;
2064:                     $request = new $request;
2065:                     $request->setAttributes($oldRequest->getAttributes(array('email')), false);
2066:                     $request->addErrors($oldRequest->getErrors());
2067:                 } else {
2068:                     // A user with the corresponding email was found. Attempt to
2069:                     // send the email and whatever happens, don't display the
2070:                     // form again.
2071:                     $scenario = 'message';
2072:                     $mail = new EmailDeliveryBehavior();
2073:                     $mail->credId = Credentials::model()->getDefaultUserAccount(
2074:                             Credentials::$sysUseId['systemNotificationEmail'], 'email');
2075: 
2076:                     // Compose the message & headers
2077:                     $message = Yii::t(
2078:                         'users', 
2079:                         "You have requested to reset the password for user {user} in {appName}.", 
2080:                         array(
2081:                             '{user}' => $request->user->alias,
2082:                             '{appName}' => Yii::app()->settings->appName
2083:                         ));
2084:                     $message .= ' ' . 
2085:                         Yii::t(
2086:                             'users', 
2087:                             "To finish resetting your password, please open the following link: ");
2088:                     $message .= "<br /><br />" . 
2089:                         $this->createAbsoluteUrl('/site/resetPassword') . '?' . 
2090:                         http_build_query(array('id' => $request->id));
2091:                     $message .= "<br /><br />" . 
2092:                         Yii::t(
2093:                             'users', 
2094:                             "If you did not make this request, please disregard this email.");
2095:                     $recipients = array(
2096:                         'to' => array(
2097:                             array('', $request->email)
2098:                         )
2099:                     );
2100: 
2101:                     // Send the email
2102:                     $status = $mail->deliverEmail(
2103:                         $recipients, Yii::app()->settings->appName . " password reset", $message);
2104: 
2105:                     // Set the response message accordingly.
2106:                     if ($status['code'] == 200) {
2107:                         $title = Yii::t('users', 'Almost Done!');
2108:                         $message = Yii::t('users', 'Check your email at {email} for '
2109:                             . 'further instructions to finish resetting your password.', 
2110:                             array('{email}' => $request->email));
2111:                     } else {
2112:                         $title = Yii::t('users', 'Could not send email.');
2113:                         $message = Yii::t(
2114:                             'users', 
2115:                             'Sending of the password reset verification email failed with '.
2116:                             'message: {message}', 
2117:                             array(
2118:                                 '{message}' => $status['message']
2119:                             ));
2120:                     }
2121:                 }
2122:             } else if ($request->limitReached) {
2123:                 $scenario = 'message';
2124:                 $message = Yii::t('app', 'You have made too many requests to reset passwords. ' . 
2125:                     'Please wait one hour before trying again.');
2126:             }
2127:         } else if ($id !== null) {
2128:             // User might have arrived here through the link in a reset email.
2129:             $scenario = 'apply';
2130:             $request = PasswordReset::model()->findByPk($id);
2131:             if ($request instanceof PasswordReset && !$request->isExpired) {
2132:                 // Reset request record exists.
2133:                 $user = $request->user;
2134:                 if ($user instanceof User) {
2135:                     // ...and is valid (points to an existing user)
2136:                     //
2137:                     // Default message: the password entry form (initial request)
2138:                     $message = Yii::t(
2139:                         'users', 'Enter a new password for user "{user}" ({name}):', array(
2140:                             '{user}' => $user->alias,
2141:                             '{name}' => CHtml::encode($user->firstName . ' ' . $user->lastName)
2142:                     ));
2143:                     $resetForm = new PasswordResetForm($user);
2144:                     if (isset($_POST['PasswordResetForm'])) {
2145:                         // Handle the form submission:
2146:                         $resetForm->setAttributes($_POST['PasswordResetForm']);
2147:                         if ($resetForm->save()) {
2148:                             // Done, success.
2149:                             $scenario = 'message';
2150:                             $title = Yii::t('users', 'Password Has Been Reset');
2151:                             $message = Yii::t(
2152:                                 'users', 'You should now have access as "{user}" with the new '.
2153:                                 'password specified.', array('{user}' => $user->alias));
2154:                         }
2155:                     }
2156:                 } else {
2157:                     // Invalid request record; it does not correspond to an
2158:                     // existing user, i.e. it's an "attempt" (entering an email
2159:                     // address to see if that sticks).
2160:                     $scenario = 'message';
2161:                     $title = Yii::t('users', 'Access Denied');
2162:                     $message = Yii::t('users', 'Invalid reset key.');
2163:                 }
2164:             } else {
2165:                 $scenario = 'message';
2166:                 $title = Yii::t('users', 'Access Denied');
2167:                 if ($request->isExpired) {
2168:                     $message = Yii::t('users', 'The password reset link has expired.');
2169:                 } else {
2170:                     $message = Yii::t('users', 'Invalid reset link.');
2171:                 }
2172:             }
2173:         }
2174:         return compact('scenario', 'title', 'message', 'request', 'resetForm');
2175:     }
2176: 
2177:     /**
2178:      * Reset a user's password via a really basic email verification process
2179:      *
2180:      * @param type $id ID/key of the password recovery record
2181:      */
2182:     public function actionResetPassword($id = null) {
2183:         if (!Yii::app()->user->isGuest) {
2184:             $this->redirect(array('/profile/changePassword', 'id' => Yii::app()->user->id));
2185:         }
2186:         $this->layout = '//layouts/login';
2187:         $title = Yii::t('app', 'Reset Password');
2188:         $this->pageTitle = $title;
2189:         $loginRoute = '/site/login';
2190:         extract ($this->resetPasswordHelper ($id, $title));
2191:         $this->render(
2192:             'resetPassword', compact(
2193:                 'scenario', 'title', 'message', 'request', 'resetForm', 'loginRoute'));
2194:     }
2195: 
2196:     /**
2197:      * Prints a very brief help page
2198:      */
2199:     public function actionAnonHelp() {
2200:         $this->layout = '//layouts/login';
2201:         $this->render('anonHelp');
2202:     }
2203: 
2204:     public function actionDuplicateCheck(
2205:     $moduleName, $modelName, $id = null, $ref = 'view', $showAll = false) {
2206: 
2207:         if (empty($id)) {
2208:             $model = X2Model::model($modelName);
2209:             $attributes = Yii::app()->user->getState('json_attributes');
2210:             $model->attributes = json_decode($attributes, true);
2211:         } else {
2212:             $model = X2Model::model($modelName)->findByPk($id);
2213:         }
2214:         if ($model->asa('X2DuplicateBehavior')) {
2215:             $this->render('duplicateCheck', array(
2216:                 'count' => $model->countDuplicates(),
2217:                 'newRecord' => $model,
2218:                 'duplicates' => $model->getDuplicates($showAll),
2219:                 'ref' => $ref,
2220:                 'modelName' => $modelName,
2221:                 'moduleName' => $moduleName,
2222:             ));
2223:         } else {
2224:             
2225:         }
2226:     }
2227: 
2228:     public function actionResolveDuplicates() {
2229:         if (isset($_POST['action'], $_POST['ref'], $_POST['modelName'])) {
2230:             $action = $_POST['action'];
2231:             $ref = $_POST['ref'];
2232:             $modelName = $_POST['modelName'];
2233:             $id = null;
2234:             // Keep this tells us to do nothing, but we still need to mark the
2235:             // original model as having been checked for duplicates
2236:             if ($action === 'keepThis' && isset($_POST['data'])) {
2237:                 $attributes = json_decode($_POST['data'], true);
2238:                 if ($ref !== 'create') {
2239:                     $model = $modelName::model()->findByPk($attributes['id']);
2240:                     $model->duplicateChecked();
2241:                     $id = $model->id;
2242:                 } else {
2243:                     $model = new $modelName;
2244:                     // If we want to keep a newly created record, we have to finish creation
2245:                     foreach ($attributes as $key => $value) {
2246:                         if ($key !== 'id') {
2247:                             $model->$key = $value;
2248:                         }
2249:                     }
2250:                     $model->save();
2251:                     $model->duplicateChecked();
2252:                     $id = $model->id;
2253:                 }
2254:             } elseif ($action === 'ignoreNew' && isset($_POST['data']) && $ref !== 'create') {
2255:                 $attributes = json_decode($_POST['data'], true);
2256:                 $model = X2Model::model($modelName)->findByPk($attributes['id']);
2257:                 $model->markAsDuplicate();
2258:             } elseif (($action === 'deleteNew' || ($action === 'ignoreNew' && $ref === 'create')) && isset($_POST['data'])) {
2259:                 if ($ref === 'create') {
2260:                     return;
2261:                 } elseif (isset($_POST['data'])) {
2262:                     $attributes = json_decode($_POST['data'], true);
2263:                     $model = X2Model::model($modelName)->findByPk($attributes['id']);
2264:                     $model->markAsDuplicate('delete');
2265:                 }
2266:             }  elseif (empty($action) && isset($_POST['data'])) {
2267:                 $attributes = json_decode($_POST['data'], true);
2268:                 $model = X2Model::model($modelName)->findByPk($attributes['id']);
2269:             }
2270:             // Modifier determines additional steps to take like hiding or deleting other records
2271:             if (isset($_POST['modifier'], $model)) {
2272:                 switch ($_POST['modifier']) {
2273:                     case 'hideAll':
2274:                         $model->hideDuplicates();
2275:                         break;
2276:                     case 'deleteAll':
2277:                         $model->deleteDuplicates();
2278:                         break;
2279:                     case 'hideThis':
2280:                         $model->markAsDuplicate();
2281:                         break;
2282:                     case 'deleteThis':
2283:                         $model->markAsDuplicate('delete');
2284:                         break;
2285:                 }
2286:             }
2287:             echo $id;
2288:         }
2289:     }
2290: 
2291:     public function actionGetSkypeLink(array $usernames) {
2292:         echo X2Html::renderSkypeLink($usernames);
2293:     }
2294: 
2295:     
2296: 
2297:     /**
2298:      * Save model attributes POSTed by inline edit form.
2299:      */
2300:     public function actionAjaxSave() {
2301:         if (isset($_POST['modelId'], $_POST['attributes'])) {
2302:             $attributes = array();
2303:             $modelName = null;
2304:             foreach ($_POST['attributes'] as $attr => $val) {
2305:                 $pieces = explode('[', $attr);
2306:                 if (is_null($modelName)) {
2307:                     $modelName = $pieces[0];
2308:                 }
2309:                 $attribute = str_replace(']', '', $pieces[1]);
2310:                 $attributes[$attribute] = $val;
2311:             }
2312: 
2313:             $model = X2Model::model($modelName)->findByPk($_POST['modelId']);
2314: 
2315:             if (isset($model) && Yii::app()->controller->checkPermissions($model, 'edit')) {
2316:                 $model->setX2Fields($attributes);
2317:                 if ($model->save()) {
2318:                     $retArr = array();
2319:                     foreach (array_intersect_key(
2320:                         $model->attributes, $attributes) as $attr => $key) {
2321: 
2322:                         $retArr[$modelName . '_' . $attr] = $model->renderAttribute(
2323:                             $attr, true, false);
2324:                     }
2325:                     echo CJSON::encode (array (
2326:                         'updatedFields' => $retArr
2327:                     ));
2328:                 } else {
2329:                     $errorMessages = $model->getAllErrorMessages ();
2330:                     $errorMessages['header'] = Yii::t(
2331:                         'app', '{modelName} could not be updated:', array (
2332:                             '{modelName}' => $model->getDisplayName (false),
2333:                         ));
2334:                     echo CJSON::encode (array (
2335:                         'errors' => $errorMessages,
2336:                     ));
2337:                 }
2338:             }
2339:         }
2340:     }
2341: 
2342:     /**
2343:      * Action called to mark a tour (tip) as seen
2344:      * @param  int $id ID of the tip
2345:      */
2346:     public function actionTourSeen ($id) {
2347:         Tours::model()->updateByPk ($id, 
2348:             array('seen' => true)
2349:         );
2350: 
2351:         echo 'success';
2352:     }
2353: 
2354: 
2355:     /**
2356:      * Gets a preview of a layout form for the form editor
2357:      * @param  $_POST[modelName] Name of the model to preview
2358:      * @param  $_POST[layout]  JSON Encoded layout  to preview
2359:      * @return  Echoes out HTML
2360:      */
2361:     public function actionLayoutPreview() {
2362:         $modelName = $_POST['modelName'];
2363:         $layout = CJSON::decode($_POST['layout']);
2364: 
2365:         $model = new $modelName;
2366:         $config = array(
2367:             'model' => $model,
2368:             'layoutData' => $layout,
2369:             'scenario' => 'Inline',
2370:             'formSettings' => array (),
2371:         );
2372:         echo '<div id="preview-form">';
2373:         $this->widget ('FormView', $config);
2374:         echo '</div>';
2375: 
2376:         echo '<div id="preview-view">';
2377:         $this->widget ('DetailView', $config);
2378:         echo '</div>';
2379:     }
2380: 
2381: 
2382: }
2383: 
X2CRM Documentation API documentation generated by ApiGen 2.8.0