Example #1
0
 /**
  * Generates a default layout from the desktop layout if available, or from the model's
  * fields otherwise.
  * @param string $type 'form' or 'view'
  * @param string $modelName
  * @return array
  */
 public static function generateDefaultLayout($type, $modelName)
 {
     if ($type === 'form') {
         $layout = FormLayout::model()->findByAttributes(array('model' => ucfirst($modelName), 'defaultForm' => 1, 'scenario' => 'Default'));
     } else {
         $layout = FormLayout::model()->findByAttributes(array('model' => ucfirst($modelName), 'defaultView' => 1, 'scenario' => 'Default'));
     }
     $layoutData = array();
     if ($layout) {
         $layout = CJSON::decode($layout->layout);
         if (isset($layout['sections'])) {
             foreach ($layout['sections'] as $section) {
                 foreach ($section['rows'] as $row) {
                     foreach ($row['cols'] as $col) {
                         foreach ($col['items'] as $item) {
                             if (isset($item['name'])) {
                                 $fieldName = preg_replace('/^formItem_/u', '', $item['name']);
                                 $layoutData[] = $fieldName;
                             }
                         }
                     }
                 }
             }
         }
     } elseif (is_subclass_of($modelName, 'X2Model')) {
         $layoutData = Yii::app()->db->createCommand()->select('fieldName')->from('x2_fields')->where('modelName=:modelName', array(':modelName' => $modelName))->andWhere($type === 'view' ? 'readOnly' : 'true')->queryColumn();
     }
     return $layoutData;
 }
Example #2
0
 /**
  * Import a set of CSV data into the software.
  *
  * This function is called via AJAX and is the meat of the global import process.
  * It takes the variable "count" as POST data to determine how many records
  * it should import in this step, which is usually 50, but is arbitrary
  * except for server load considerations. It reads data out of the "data.csv"
  * file and imports it. See inline comments for details of what's going on.
  *
  * @return null A return statement to cease further execution, could probably be cleaned up & removed
  */
 public function actionGlobalImport()
 {
     if (isset($_POST['count']) && file_exists($this->safePath())) {
         $metaData = $_SESSION['metaData'];
         // Grab the most recent metadata
         $modelType = $_SESSION['model'];
         // And model
         $count = $_POST['count'];
         $fp = fopen($this->safePath(), 'r+');
         /*
          * THIS IS ESSENTIAL. As with the above block noted as essential,
          * this was KEY to figuring out how to do an AJAX based CSV read.
          * The fseek function will move the file pointer to the specified offset,
          * which we always store in the $_SESSION['offset'] variable.
          */
         fseek($fp, $_SESSION['offset']);
         for ($i = 0; $i < $count; $i++) {
             // Loop up to the speficied count.
             $arr = fgetcsv($fp);
             // Grab the next row
             if ($arr !== false && !is_null($arr)) {
                 while ("" === end($arr)) {
                     // Remove blank space from the end
                     array_pop($arr);
                 }
                 $newType = array_pop($arr);
                 // Pull the last column to check the model type
                 if ($newType != $modelType) {
                     /*
                      * If this is the first row of a new model type, the data
                      * in the last column will be a different class name. In that
                      * case, we assume this new row consists of the metadata
                      * for this new model class and that the next set of records
                      * will be of this model type. This information is stored
                      * in the session in case a set of 50 records breaks
                      * unevenly across model types (e.g. the system needs to import
                      * more than 50 of a given record).
                      */
                     $_SESSION['model'] = $newType;
                     $_SESSION['metaData'] = $arr;
                     $modelType = $_SESSION['model'];
                     $metaData = $_SESSION['metaData'];
                 } else {
                     $attributes = array_combine($metaData, $arr);
                     if ($modelType == "Actions" && (isset($attributes['type']) && $attributes['type'] == 'workflow')) {
                         // In the event that we're importing workflow, we need a special
                         // scenario.
                         $model = new Actions('workflow');
                     } else {
                         $model = new $modelType();
                     }
                     /*
                      * This loops through and sets the attributes manually.
                      * Realistically, this could be refactored to use the
                      * SetX2Fields function, but you'd need to be sure the
                      * data wasn't double formatted (e.g. it's already a unix
                      * timestamp, not a date string, and doesn't need to be
                      * converted again) due to the fact that a user could supply
                      * either human readable or machine readable data.
                      */
                     foreach ($attributes as $key => $value) {
                         if ($model->hasAttribute($key) && isset($value)) {
                             if ($value == "") {
                                 $value = null;
                             }
                             $model->{$key} = $value;
                         }
                     }
                     // Don't make a changelog record.
                     $model->disableBehavior('changelog');
                     // Don't manually set the timestamp fields
                     $model->disableBehavior('X2TimestampBehavior');
                     if ($model instanceof User || $model instanceof Profile) {
                         if ($model->id == '1') {
                             /*
                              * If a model of type User with the ID of one is
                              * being imported skip so that we DO NOT
                              * OVERWRITE THE CURRENT ADMIN USER.
                              */
                             continue;
                         }
                         // Users & Profile normally require special validation, set a scenario for import
                         $model->setScenario('import');
                     }
                     if ($_SESSION['overwrite'] == 1 && property_exists($model, 'subScenario')) {
                         $model->subScenario = 'importOverwrite';
                     }
                     // If an ID was provided, check if there's already a model with that ID
                     $lookup = X2Model::model($modelType)->findByPk($model->id);
                     $lookupFlag = isset($lookup);
                     /*
                      * I'm not sure if "validate" will succeed anymore given the
                      * change made to ID being a "unique" field in X2Model's rules
                      * This should be investigated at some point.
                      */
                     if ($model->validate() || $modelType == "User" || $modelType == 'Profile') {
                         $saveFlag = true;
                         if ($lookupFlag) {
                             if ($_SESSION['overwrite'] == 1) {
                                 // If the user specified to overwrite, delete the old lookup
                                 if ($modelType === "Fields") {
                                     /**
                                      * Leave fields intact; the record information would be deleted when
                                      * the column is removed by Fields' afterDelete hook.
                                      */
                                     continue;
                                 }
                                 $lookup->disableBehavior('changelog');
                                 $lookup->delete();
                             } else {
                                 $saveFlag = false;
                                 // Otherwise, note a failure in the logging section that we were unable to overwrite a record.
                                 isset($_SESSION['overwriteFailure'][$modelType]) ? $_SESSION['overwriteFailure'][$modelType]++ : ($_SESSION['overwriteFailure'][$modelType] = 1);
                             }
                             if (!$model->validate()) {
                                 $saveFlag = false;
                                 $failedImport = fopen($this->safePath('failedImport.csv'), 'a+');
                                 $lastFailed = $_SESSION['lastFailed'];
                                 if ($lastFailed != $modelType) {
                                     $tempMeta = $metaData;
                                     // Keep track of the metadata of failed records
                                     $tempMeta[] = $modelType;
                                     fputcsv($failedImport, $tempMeta);
                                 }
                                 $attr = $model->attributes;
                                 $tempAttributes = X2Model::model($modelType)->attributes;
                                 $attr = array_merge($tempAttributes, $attr);
                                 $attr[] = $modelType;
                                 fputcsv($failedImport, $attr);
                                 $_SESSION['lastFailed'] = $modelType;
                                 // Specify the most recent model type failure in case metadata needs to be changed
                                 isset($_SESSION['failed']) ? $_SESSION['failed']++ : ($_SESSION['failed'] = 1);
                             }
                         }
                         if ($saveFlag && $model->save()) {
                             if ($modelType != "Admin" && !(($modelType == "User" || $modelType == "Profile") && ($model->id == '1' || $model->username == 'api'))) {
                                 // Generate a new "Imports" model in case of rollback
                                 $importLink = new Imports();
                                 $importLink->modelType = $modelType;
                                 $importLink->modelId = $model->id;
                                 $importLink->importId = $_SESSION['importId'];
                                 $importLink->timestamp = time();
                                 $importLink->save();
                             }
                             if ($modelType === "Fields") {
                                 // If we're creating a field, we must also recreate the
                                 // respective table index
                                 if (isset($model->keyType)) {
                                     $model->createIndex($model->keyType === "UNI");
                                 }
                             } else {
                                 if ($modelType === "FormLayout") {
                                     /*
                                      Ensure default form settings are maintained. If overwrite
                                      is set, the most recently imported layout will be set to
                                      default, otherwise the default flags for the newly imported
                                      layout will be cleared.
                                     */
                                     if ($_SESSION['overwrite']) {
                                         if ($model->defaultView) {
                                             FormLayout::clearDefaultFormLayouts('view', $model->model);
                                         }
                                         if ($model->defaultForm) {
                                             FormLayout::clearDefaultFormLayouts('form', $model->model);
                                         }
                                         $model->save();
                                     } else {
                                         $model->defaultView = false;
                                         $model->defaultForm = false;
                                         $model->save();
                                     }
                                 }
                             }
                             // Relic of when action description wasn't a field, not sure if necessary.
                             if ($modelType == 'Actions' && isset($attributes['actionDescription'])) {
                                 $model->actionDescription = $attributes['actionDescription'];
                             }
                             // Update counts in the session logging variables.
                             isset($_SESSION['counts'][$modelType]) ? $_SESSION['counts'][$modelType]++ : ($_SESSION['counts'][$modelType] = 1);
                             if ($lookupFlag) {
                                 isset($_SESSION['overwriten'][$modelType]) ? $_SESSION['overwriten'][$modelType]++ : ($_SESSION['overwriten'][$modelType] = 1);
                             } else {
                                 isset($_SESSION['overwriten'][$modelType]) ?: ($_SESSION['overwriten'][$modelType] = 0);
                             }
                         }
                     } else {
                         // Put the failed lead into the failed import CSV
                         //AuxLib::debugLogR ('failed to import '.get_class ($model));
                         //AuxLib::debugLogR ($model->getErrors ());
                         $failedImport = fopen($this->safePath('failedImport.csv'), 'a+');
                         $lastFailed = $_SESSION['lastFailed'];
                         if ($lastFailed != $modelType) {
                             $tempMeta = $metaData;
                             $tempMeta[] = $modelType;
                             fputcsv($failedImport, $tempMeta);
                         }
                         $attr = $model->attributes;
                         $tempAttributes = X2Model::model($modelType)->attributes;
                         $attr = array_merge($tempAttributes, $attr);
                         $attr[] = $modelType;
                         fputcsv($failedImport, $attr);
                         $_SESSION['lastFailed'] = $modelType;
                         isset($_SESSION['failed']) ? $_SESSION['failed']++ : ($_SESSION['failed'] = 1);
                     }
                 }
             } else {
                 // "0" at the beginning means we reached the end of the file
                 // and don't need to do another set.
                 echo json_encode(array(0, json_encode($_SESSION['counts']), json_encode($_SESSION['overwriten']), json_encode($_SESSION['failed']), json_encode($_SESSION['overwriteFailure'])));
                 return;
             }
         }
         // Update the file offset pointer in the session.
         $_SESSION['offset'] = ftell($fp);
         echo json_encode(array(1, json_encode($_SESSION['counts']), json_encode($_SESSION['overwriten']), json_encode($_SESSION['failed']), json_encode($_SESSION['overwriteFailure'])));
     }
 }
Example #3
0
 public function getLayoutData()
 {
     $layoutData = Yii::app()->cache->get('form_' . $this->modelName . '_' . $this->scenario);
     if ($layoutData) {
         return $layoutData;
     }
     $layout = FormLayout::model()->findByAttributes(array('model' => ucfirst($this->modelName), 'defaultView' => 1, 'scenario' => $this->scenario));
     if (!$layout && $this->scenario === 'Inline') {
         $layout = FormLayout::model()->findByAttributes(array('model' => ucfirst($this->modelName), 'defaultView' => 1, 'scenario' => 'Default'));
     }
     if (isset($layout)) {
         $layoutData = json_decode($layout->layout, true);
         Yii::app()->cache->set('form_' . $this->modelName . '_' . $this->scenario, $this->layoutData, 0);
         // cache the data
     }
     return $layoutData;
 }
Example #4
0
 * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 ********************************************************************************/
$attributeLabels = $model->attributeLabels();
$showSocialMedia = Yii::app()->params->profile->showSocialMedia;
$showWorkflow = Yii::app()->params->profile->showWorkflow;
if ($modelName == 'contacts' || $modelName == 'sales') {
    Yii::app()->clientScript->registerScript('toggleWorkflow', "\nfunction showWorkflow() {\n\t\$('tr#workflow-row').show();\n\t\$('tr#workflow-toggle').hide();\n}\nfunction hideWorkflow() {\n\t\$('tr#workflow-row').hide();\n\t\$('tr#workflow-toggle').show();\n}\n\$(function() {\n" . ($showWorkflow ? "showWorkflow();\n" : "hideWorkflow()\n") . "});", CClientScript::POS_HEAD);
    Yii::app()->clientScript->registerScript('setFormName', "\nwindow.formName = '{$modelName}';\n", CClientScript::POS_HEAD);
}
$layout = FormLayout::model()->findByAttributes(array('model' => ucfirst($modelName), 'defaultView' => 1));
if (isset($layout)) {
    echo '<div class="x2-layout">';
    $fields = array();
    // remove this later, once all models extend X2Models
    if (method_exists($model, 'getFields')) {
        foreach ($model->fields as $fieldModel) {
            $fields[$fieldModel->fieldName] = $fieldModel;
        }
    } else {
        foreach (Fields::model()->findAllByAttributes(array('modelName' => ucfirst($modelName))) as $fieldModel) {
            $fields[$fieldModel->fieldName] = $fieldModel;
        }
    }
    $layoutData = json_decode($layout->layout, true);
    $formSettings = ProfileChild::getFormSettings($modelName);
Example #5
0
 /**
  * Helper method to unset all defaultView or defaultForm flags
  * @param string $type Form type, either 'view' or 'form', or both if argument is omitted
  * @param string Model type to unset flags for
  */
 public static function clearDefaultFormLayouts($type = null, $model = null, $scenario = null)
 {
     // Construct attributes to select form layouts
     $attr = array('model' => $model);
     if ($scenario) {
         $attr['scenario'] = $scenario;
     }
     if ($type === 'view') {
         $attr['defaultView'] = 1;
     } else {
         if ($type === 'form') {
             $attr['defaultForm'] = 1;
         }
     }
     $layouts = FormLayout::model()->findAllByAttributes($attr);
     foreach ($layouts as &$layout) {
         if ($type === 'view') {
             $layout->defaultView = false;
         } else {
             if ($type === 'form') {
                 $layout->defaultForm = false;
             } else {
                 $layout->defaultView = $layout->defaultForm = false;
             }
         }
         $layout->save();
     }
 }
 /**
  * @param mixed $models
  * @param null $header
  * @param null $footer
  * @param array $htmlOptions
  * @return string
  */
 public function errorSummary($models, $header = null, $footer = null, $htmlOptions = array())
 {
     if (!isset($htmlOptions['class'])) {
         $htmlOptions['class'] = 'alert-box alert with-icon';
     }
     return parent::errorSummary($models, $header, $footer, $htmlOptions);
 }
 public function getLayout()
 {
     return FormLayout::model()->findByAttributes(array('model' => ucfirst($this->modelName), 'defaultForm' => 1, 'scenario' => 'Default'));
 }
Example #8
0
 public function actionQuickView($id)
 {
     $model = $this->loadModel($id);
     if (!FormLayout::model()->findByAttributes(array('model' => get_class($model)))) {
         echo Yii::t('app', 'Quick view not supported');
     }
     if ($this->checkPermissions($model, 'view')) {
         $this->widget('DetailView', array_merge(array('model' => $model, 'scenario' => 'Inline', 'nameLink' => true)), false, true);
         // $this->renderPartial(
         // 'application.components.views.@DETAILVIEW',
         //     array_merge( array(
         //         'model' => $model,
         //         'modelName' => get_class ($model),
         //         'scenario'=>'Inline',
         //         'nameLink' => true,
         //     ), $options)
         // , false, true);
         return;
     }
     throw new CHttpException(403);
 }
Example #9
0
 public function actionQuickView($id)
 {
     $model = $this->loadModel($id);
     if (!FormLayout::model()->findByAttributes(array('model' => get_class($model)))) {
         echo Yii::t('app', 'Quick view not supported');
     }
     if ($this->checkPermissions($model, 'view')) {
         $that = $this;
         X2Widget::ajaxRender(function () use($model, $that) {
             $that->widget('DetailView', array_merge(array('model' => $model, 'scenario' => 'Inline', 'nameLink' => true)));
         });
         return;
     }
     throw new CHttpException(403);
 }
Example #10
0
                                    return $("<li>").data("item.autocomplete",item).append(
                                        x2.forms.renderContactLookup(item)).appendTo(ul);
                                };
                            }'), 'htmlOptions' => array('style' => 'max-width:200px;')), true) . CHtml::tag('span', array('class' => 'x2-hint', 'style' => 'display:inline-block; margin-left:5px;', 'title' => Yii::t('marketing', 'The {contact} you enter here will be used for variable replacement, ' . 'i.e. for "John Doe" the token {firstName} will get replaced with ' . '"John"', array('{contact}' => Modules::displayName(false, "Contacts")))), '[?]') . '</div>'));
if ($model->type === 'Email') {
    ?>
        <?php 
    if ($model->launchDate && $model->active && !$model->complete) {
        $this->widget('EmailProgressControl', array('campaign' => $model));
    }
    ?>
        <?php 
    // find out if attachments are minimized
    $showAttachments = true;
    $formSettings = Profile::getFormSettings('campaign');
    $layout = FormLayout::model()->findByAttributes(array('model' => 'Campaign', 'defaultView' => 1));
    if (isset($layout)) {
        $layoutData = json_decode($layout->layout, true);
        $count = count($layoutData['sections']);
        if (isset($formSettings[$count])) {
            $showAttachments = $formSettings[$count];
        }
    }
    ?>

        <div id="campaign-attachments-wrapper" class="x2-layout form-view">
            <div class="formSection collapsible <?php 
    echo $showAttachments ? 'showSection' : '';
    ?>
">
                <div class="formSectionHeader">
Example #11
0
 * technical reasons, the Appropriate Legal Notices must display the words
 * "Powered by X2Engine".
 *****************************************************************************************/
/**
 * @params bool $suppressQuickCreate if true, does not display quick create buttons for lookup
 *  type fields
 * @param bool $suppressForm if true, does not wrap html in an active form widget
 * @param array $defaultsByRelatedModelType (<model type> => <array of default arguments>). Used
 *  as arguments to RelationshipsManager JS prototype for each of the quick create buttons.
 */
// Construct criteria for finding the right form layout.
$attributes = array('model' => ucfirst($modelName), 'defaultForm' => 1);
// If the $scenario variable is set in the rendering context, a special
// different form should be retrieved.
$attributes['scenario'] = isset($scenario) ? $scenario : 'Default';
$layout = FormLayout::model()->findByAttributes($attributes);
if (isset($layout)) {
    $layoutData = json_decode($layout->layout, true);
}
if (isset($layoutData['version']) && version_compare($layoutData['version'], '5.2') >= 0) {
    $this->widget('FormView', array('model' => $model));
} else {
    Yii::app()->clientScript->registerScript('formUIScripts', "\n\$('.x2-layout.form-view :input').change(function() {\n    \$('#save-button, #save-button1, #save-button2, h2 a.x2-button').addClass('highlight');\n});\n", CClientScript::POS_READY);
    Yii::app()->clientScript->registerScript('datePickerDefault', "\n    \$.datepicker.setDefaults (\$.datepicker.regional['']);\n", CClientScript::POS_READY);
    Yii::app()->clientScript->registerCssFile(Yii::app()->theme->baseUrl . '/css/recordEdit.css');
    Yii::app()->clientScript->registerScript('setFormName', "\nwindow.formName = '{$modelName}';\n", CClientScript::POS_HEAD);
    $renderFormTags = !isset($form);
    if (isset($suppressForm) && !$suppressForm || !isset($suppressForm)) {
        if ($renderFormTags) {
            $form = $this->beginWidget('CActiveForm', array('id' => $modelName . '-form', 'enableAjaxValidation' => false));
        }
Example #12
0
 public function getLayoutData()
 {
     $attributes = array('model' => ucfirst($this->modelName), 'defaultForm' => 1, 'scenario' => $this->scenario);
     $layout = FormLayout::model()->findByAttributes($attributes);
     return CJSON::decode($layout->layout);
 }
 public function actionDeleteFormLayout($id)
 {
     $layout = FormLayout::model()->findByPk($id);
     if (isset($layout)) {
         $modelName = $layout->model;
         $defaultView = $layout->defaultView;
         $defaultForm = $layout->defaultForm;
         $layout->delete();
         // if we just deleted the default, find the next layout and make it the default
         if ($defaultView) {
             $newDefaultView = FormLayout::model()->findByAttributes(array('model' => $modelName));
             if (isset($newDefaultView)) {
                 $newDefaultView->defaultView = true;
                 $newDefaultView->save();
             }
         }
         if ($defaultForm) {
             $newDefaultForm = FormLayout::model()->findByAttributes(array('model' => $modelName));
             if (isset($newDefaultForm)) {
                 $newDefaultForm->defaultForm = true;
                 $newDefaultForm->save();
             }
         }
         $this->redirect(array('editor', 'model' => $modelName));
     } else {
         $this->redirect('editor');
     }
 }