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

  • AccountsGridViewProfileWidget
  • ActionMenu
  • ActionsGridViewProfileWidget
  • ActionsQuickCreateRelationshipBehavior
  • ActiveDateRangeInput
  • ApplicationConfigBehavior
  • Attachments
  • ChatBox
  • CommonControllerBehavior
  • ContactMapInlineTags
  • ContactsGridViewProfileWidget
  • CronForm
  • CSaveRelationsBehavior
  • DateRangeInputsWidget
  • DocsGridViewProfileWidget
  • DocViewer
  • DocViewerProfileWidget
  • EButtonColumnWithClearFilters
  • EmailDeliveryBehavior
  • EmailProgressControl
  • EncryptedFieldsBehavior
  • EventsChartProfileWidget
  • FileUploader
  • FontPickerInput
  • Formatter
  • FormView
  • GridViewWidget
  • History
  • IframeWidget
  • ImportExportBehavior
  • InlineActionForm
  • InlineEmailAction
  • InlineEmailForm
  • InlineEmailModelBehavior
  • InlineQuotes
  • JSONEmbeddedModelFieldsBehavior
  • JSONFieldsDefaultValuesBehavior
  • LeadRoutingBehavior
  • LeftWidget
  • LoginThemeHelper
  • LoginThemeHelperBase
  • MarketingGridViewProfileWidget
  • MediaBox
  • MessageBox
  • MobileFormatter
  • MobileFormLayoutRenderer
  • MobileLayoutRenderer
  • MobileLoginThemeHelper
  • MobileViewLayoutRenderer
  • ModelFileUploader
  • NewWebLeadsGridViewProfileWidget
  • NormalizedJSONFieldsBehavior
  • NoteBox
  • OnlineUsers
  • OpportunitiesGridViewProfileWidget
  • Panel
  • ProfileDashboardManager
  • ProfileGridViewWidget
  • ProfileLayoutEditor
  • ProfilesGridViewProfileWidget
  • Publisher
  • PublisherActionTab
  • PublisherCalendarEventTab
  • PublisherCallTab
  • PublisherCommentTab
  • PublisherEventTab
  • PublisherSmallCalendarEventTab
  • PublisherTab
  • PublisherTimeTab
  • QuickContact
  • QuickCreateRelationshipBehavior
  • QuotesGridViewProfileWidget
  • RecordAliasesWidget
  • RecordViewLayoutManager
  • RecordViewWidgetManager
  • RememberPagination
  • Reminders
  • ResponseBehavior
  • ResponsiveHtml
  • SearchIndexBehavior
  • ServicesGridViewProfileWidget
  • SmallCalendar
  • SmartActiveDataProvider
  • SmartDataProviderBehavior
  • SmartSort
  • SocialForm
  • SortableWidgetManager
  • SortableWidgets
  • TagBehavior
  • TagCloud
  • TemplatesGridViewProfileWidget
  • TimeZone
  • TopContacts
  • TopSites
  • TransformedFieldStorageBehavior
  • TranslationLogger
  • TwitterFeed
  • TwoColumnSortableWidgetManager
  • UpdaterBehavior
  • UpdatesForm
  • UserIdentity
  • UsersChartProfileWidget
  • WorkflowBehavior
  • X2ActiveGridView
  • X2ActiveGridViewForSortableWidgets
  • X2AssetManager
  • X2AuthManager
  • X2ChangeLogBehavior
  • X2ClientScript
  • X2Color
  • X2DateUtil
  • X2FixtureManager
  • X2FlowFormatter
  • X2GridView
  • X2GridViewBase
  • X2GridViewForSortableWidgets
  • X2GridViewSortableWidgetsBehavior
  • X2LeadsGridViewProfileWidget
  • X2LinkableBehavior
  • X2ListView
  • X2PillBox
  • X2ProgressBar
  • X2SmartSearchModelBehavior
  • X2TimestampBehavior
  • X2TranslationBehavior
  • X2UrlRule
  • X2WebModule
  • X2Widget
  • X2WidgetList
  • 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:  * Renders a CListView containing all actions associated with the specified model
 40:  *
 41:  * @package application.components
 42:  */
 43: class History extends X2Widget {
 44: 
 45:     public $associationType;  // type of record to associate actions with
 46:     public $associationId = '';  // record to associate actions with
 47:     public $filters = true;  // whether or not action types can be filtered on
 48:     public $historyType = 'all'; // default filter type
 49:     public $pageSize = 10; // how many records to show per page
 50:     public $relationships = 0; // don't show actions on related records by default
 51: 
 52:     public static function getCriteria(
 53:     $associationId, $associationType, $relationships, $historyType) {
 54: 
 55:         // Based on our filter, we need a particular additional criteria
 56:         $historyCriteria = array(
 57:             'all' => '',
 58:             'action' => ' AND type IS NULL',
 59:             'overdueActions' => ' AND type IS NULL AND complete="NO" AND dueDate <= ' . time(),
 60:             'incompleteActions' => ' AND type IS NULL AND complete="NO"',
 61:             'call' => ' AND type="call"',
 62:             'note' => ' AND type="note"',
 63:             'attachments' => ' AND type="attachment"',
 64:             'event' => ' AND type="event"',
 65:             'email' =>
 66:             ' AND type IN ("email","email_staged","emailFrom",' .
 67:             '"email_opened","email_clicked","email_unsubscribed")',
 68:             'marketing' =>
 69:             ' AND type IN ("email","webactivity","weblead","email_staged",' .
 70:             '"email_opened","email_clicked","email_unsubscribed","event")',
 71:             
 72:             'quotes' => 'AND type like "quotes%"',
 73:             'time' => ' AND type="time"',
 74:             'webactivity' => 'AND type IN ("weblead","webactivity")',
 75:             'workflow' => ' AND type="workflow"',
 76:         );
 77:         $multiAssociationIds = array($associationId);
 78:         if ($relationships) {
 79:             // Add association conditions for our relationships
 80:             $type = $associationType;
 81:             $model = X2Model::model($type)->findByPk($associationId);
 82:             if (count($model->relatedX2Models) > 0) {
 83:                 $associationCondition = "((associationId={$associationId} AND " .
 84:                         "associationType='{$associationType}')";
 85:                 // Loop through related models and add an association type OR for each
 86:                 foreach ($model->relatedX2Models as $relatedModel) {
 87:                     if ($relatedModel instanceof X2Model) {
 88:                         $multiAssociationIds[] = $relatedModel->id;
 89:                         $associationCondition .=
 90:                                 " OR (associationId={$relatedModel->id} AND " .
 91:                                 "associationType='{$relatedModel->myModelName}')";
 92:                     }
 93:                 }
 94:                 $associationCondition.=")";
 95:             } else {
 96:                 $associationCondition = 'associationId=' . $associationId . ' AND ' .
 97:                         'associationType="' . $associationType . '"';
 98:             }
 99:         } else {
100:             $associationCondition = 'associationId=' . $associationId . ' AND ' .
101:                     'associationType="' . $associationType . '"';
102:         }
103:         /* Fudge replacing Opportunity and Quote because they're stored as plural in the actions 
104:           table */
105:         $associationCondition = str_replace('Opportunity', 'opportunities', $associationCondition);
106:         $associationCondition = str_replace('Quote', 'quotes', $associationCondition);
107:         $visibilityCondition = '';
108:         $module = isset(Yii::app()->controller->module) ?
109:                 Yii::app()->controller->module->getId() : Yii::app()->controller->getId();
110:         // Apply history privacy settings so that only allowed actions are viewable.
111:         if (!Yii::app()->user->checkAccess(ucfirst ($module) . 'Admin')) {
112:             if (Yii::app()->settings->historyPrivacy == 'user') {
113:                 $visibilityCondition = ' AND (assignedTo="' . Yii::app()->user->getName() . '")';
114:             } elseif (Yii::app()->settings->historyPrivacy == 'group') {
115:                 $visibilityCondition = ' AND (
116:                         t.assignedTo IN (
117:                             SELECT DISTINCT b.username 
118:                             FROM x2_group_to_user a 
119:                             INNER JOIN x2_group_to_user b ON a.groupId=b.groupId 
120:                             WHERE a.username="' . Yii::app()->user->getName() . '") OR 
121:                             (t.assignedTo="' . Yii::app()->user->getName() . '"))';
122:             } else {
123:                 $visibilityCondition = ' AND (visibility="1" OR assignedTo="' . Yii::app()->user->getName() . '")';
124:             }
125:         }
126:         $orderStr = 'IF(complete="No", GREATEST(createDate, IFNULL(dueDate,0), ' .
127:                 'IFNULL(lastUpdated,0)), GREATEST(createDate, ' .
128:                 'IFNULL(completeDate,0), IFNULL(lastUpdated,0))) DESC';
129:         $mainCountCmd = Yii::app()->db->createCommand()
130:                 ->select('COUNT(*)')
131:                 ->from('x2_actions t')
132:                 ->where($associationCondition .
133:                         $visibilityCondition . $historyCriteria[$historyType]);
134:         $mainCmd = Yii::app()->db->createCommand()
135:                 ->select('*')
136:                 ->from('x2_actions t')
137:                 ->where($associationCondition .
138:                         $visibilityCondition . $historyCriteria[$historyType])
139:                 ->order($orderStr);
140:         
141:         $multiAssociationIdParams = AuxLib::bindArray($multiAssociationIds);
142:         $associationCondition = '((' . $associationCondition . ') OR ' .
143:                 'x2_action_to_record.recordId in ' . AuxLib::arrToStrList(
144:                         array_keys($multiAssociationIdParams)) . ')';
145: 
146:         $associationCondition = 'x2_action_to_record.recordId in ' . AuxLib::arrToStrList(
147:                         array_keys($multiAssociationIdParams));
148:         $joinCountCmd = Yii::app()->db->createCommand()
149:                 ->select('COUNT(*)')
150:                 ->from('x2_actions t')
151:                 ->join('x2_action_to_record', 'actionId=t.id')
152:                 ->where($associationCondition . $visibilityCondition . $historyCriteria[$historyType] . ' AND 
153:                 x2_action_to_record.recordType=:recordType');
154:         $joinCmd = Yii::app()->db->createCommand()
155:                 ->select('t.*')
156:                 ->from('x2_actions t')
157:                 ->join('x2_action_to_record', 'actionId=t.id')
158:                 ->where($associationCondition . $visibilityCondition . $historyCriteria[$historyType] . ' AND 
159:                 x2_action_to_record.recordType=:recordType');
160:         
161:         $count = $mainCountCmd->union($joinCountCmd->getText())->queryScalar(array_merge(array(':recordType' => X2Model::getModelName($associationType)), $multiAssociationIdParams));
162:         return array(
163:             'cmd' => $mainCmd->union($joinCmd->getText()),
164:             'count' => $count,
165:             'params' => array_merge(array(':recordType' => X2Model::getModelName($associationType)), $multiAssociationIdParams));
166:     }
167: 
168:     /**
169:      * This renders the list view of the action history for a record.
170:      */
171:     public function run() {
172:         if ($this->filters) {
173:             // Filter tabs allowed
174:             $historyTabs = array(
175:                 'all' => Yii::t('app', 'All'),
176:                 'action' => Yii::t('app', '{actions}', array(
177:                     '{actions}' => Modules::displayName(true, 'Actions'),
178:                 )),
179:                 'overdueActions' => Yii::t('app', 'Overdue {actions}', array(
180:                     '{actions}' => Modules::displayName(true, 'Actions'),
181:                 )),
182:                 'incompleteActions' => Yii::t('app', 'Incomplete {actions}', array(
183:                     '{actions}' => Modules::displayName(true, 'Actions'),
184:                 )),
185:                 'attachments' => Yii::t('app', 'Attachments'),
186:                 'call' => Yii::t('app', 'Calls'),
187:                 'note' => Yii::t('app', 'Comments'),
188:                 'email' => Yii::t('app', 'Emails'),
189:                 'event' => Yii::t('app', 'Events'),
190:                 'marketing' => Yii::t('app', 'Marketing'),
191:                 'time' => Yii::t('app', 'Logged Time'),
192:                 
193:                 'quotes' => Yii::t('app', 'Quotes'),
194:                 'webactivity' => Yii::t('app', 'Web Activity'),
195:                 'workflow' => Yii::t('app', '{process}', array(
196:                     '{process}' => Modules::displayName(true, 'Workflow'),
197:                 )),
198:             );
199:             $profile = Yii::app()->params->profile;
200:             if (isset($profile)) { // Load their saved preferences from the profile
201:                 // No way to give truly infinite pagination, fudge it by making it 10,000
202:                 $this->pageSize = $profile->historyShowAll ? 10000 : 10;
203:                 $this->relationships = $profile->historyShowRels;
204:             }
205:             // See if we can filter for what they wanted
206:             if (isset($_GET['history']) && array_key_exists($_GET['history'], $historyTabs)) {
207:                 $this->historyType = $_GET['history'];
208:             }
209:             if (isset($_GET['pageSize'])) {
210:                 $this->pageSize = $_GET['pageSize'];
211:                 if (isset($profile)) {
212:                     // Save profile preferences
213:                     $profile->historyShowAll = $this->pageSize > 10 ? 1 : 0;
214:                     $profile->update(array('historyShowAll'));
215:                 }
216:             }
217:             if (isset($_GET['relationships'])) {
218:                 $this->relationships = $_GET['relationships'];
219:                 if (isset($profile)) {
220:                     $profile->historyShowRels = $this->relationships; // Save profile preferences
221:                     $profile->update(array('historyShowRels'));
222:                 }
223:             }
224:         } else {
225:             $historyTabs = array();
226:         }
227:         // Register JS to make the history tabs update the history when selected.
228:         Yii::app()->clientScript->registerScriptFile(
229:                 Yii::app()->getBaseUrl() . '/js/ActionHistory.js');
230:         Yii::app()->clientScript->registerScriptFile(
231:                 Yii::app()->getBaseUrl() . '/js/EnlargeableImage.js',
232:                 CClientScript::POS_END);
233:         Yii::app()->clientScript->registerScript('history-tabs', "
234:             x2.actionHistory = new x2.ActionHistory ({
235:                 relationshipFlag: {$this->relationships}
236:             });
237:         ", CClientScript::POS_END);
238: 
239:         $this->widget('application.components.X2ListView', array(
240:             'pager' => array(
241:                 'class' => 'CLinkPager',
242:                 'header' => '',
243:                 'firstPageCssClass' => '',
244:                 'lastPageCssClass' => '',
245:                 'prevPageLabel' => '<',
246:                 'nextPageLabel' => '>',
247:                 'firstPageLabel' => '<<',
248:                 'lastPageLabel' => '>>',
249:             ),
250:             'id' => 'history',
251:             'dataProvider' => $this->getHistory(),
252:             'viewData' => array(
253:                 // Pass relationship flag to the views so they can modify their layout slightly
254:                 'relationshipFlag' => $this->relationships,
255:             ),
256:             'itemView' => 'application.modules.actions.views.actions._historyView',
257:             'htmlOptions' => array('class' => 'action list-view'),
258:             'template' =>
259:             '<div class="form action-history-controls">' .
260:             CHtml::dropDownList(
261:                     'history-selector', $this->historyType, $historyTabs, array(
262:                 'class' => 'x2-select'
263:                     )
264:             ) .
265:             '<span style="margin-top:5px;" class="right">' .
266:             CHtml::link(
267:                     Yii::t('app', 'Toggle Text'), '#', array(
268:                 'id' => 'history-collapse', 'class' => 'x2-hint',
269:                 'title' =>
270:                 Yii::t('app', 'Click to toggle showing the full text of History items.')
271:                     )
272:             )
273:             . ' | ' . CHtml::link(
274:                     Yii::t('app', 'Show All'), '#', array(
275:                 'id' => 'show-history-link', 'class' => 'x2-hint',
276:                 'title' =>
277:                 Yii::t('app', 'Click to increase the number of History items shown.'),
278:                 'style' => $this->pageSize > 10 ? 'display:none;' : ''
279:                     )
280:             )
281:             . CHtml::link(
282:                     Yii::t('app', 'Show Less'), '#', array(
283:                 'id' => 'hide-history-link', 'class' => 'x2-hint', '
284:                         title' =>
285:                 Yii::t('app', 'Click to decrease the number of History items shown.'),
286:                 'style' => $this->pageSize > 10 ? '' : 'display:none;'
287:                     )
288:             )
289:             . ((!Yii::app()->user->isGuest) ?
290:                     ' | ' . CHtml::link(
291:                             Yii::t('app', 'Relationships'), '#', array(
292:                         'id' => 'show-relationships-link', 'class' => 'x2-hint',
293:                         'title' =>
294:                         Yii::t('app', 'Click to toggle showing actions associated with related records.'))) : '')
295:             . '</span></div> {sorter}{items}{pager}',
296:         ));
297:     }
298: 
299:     /**
300:      * Function to actually generate the condition and data provider for the
301:      * History CListView.
302:      * @return \CActiveDataProvider
303:      */
304:     public function getHistory() {
305:         $historyCmd = self::getCriteria(
306:                         $this->associationId, $this->associationType, $this->relationships, $this->historyType);
307:         return new CSqlDataProvider($historyCmd['cmd'], array(
308:             'totalItemCount' => $historyCmd['count'],
309:             'params' => $historyCmd['params'],
310:             'pagination' => array(
311:                 'pageSize' => $this->pageSize,
312:             ),
313:         ));
314:     }
315: 
316: }
317: 
X2CRM Documentation API documentation generated by ApiGen 2.8.0