HEX
Server: Apache
System: Linux WWW 6.1.0-40-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.153-1 (2025-09-20) x86_64
User: web11 (1011)
PHP: 8.2.29
Disabled: NONE
Upload Files
File: /var/www/apklausos/application/models/SurveysGroups.php
<?php

/**
 * This is the model class for table "{{surveys_groups}}".
 *
 * The following are the available columns in table '{{surveys_groups}}':
 * @property integer $gsid
 * @property string $name
 * @property string $title
 * @property string $description
 * @property integer $sortorder
 * @property integer $owner_id
 * @property integer $parent_id
 * @property boolean|integer $alwaysavailable
 * @property string $created
 * @property string $modified
 * @property integer $created_by
 * @property object $parentgroup
 * @property boolean $hasSurveys
 */
class SurveysGroups extends LSActiveRecord implements PermissionInterface
{
    use PermissionTrait;

    /* @var boolean|integer alwaysavailable : set default, and set for old DB , usage of integer for DB compatibility */
    public $alwaysavailable = 0;

    /**
     * @return string the associated database table name
     */
    public function tableName()
    {
        return '{{surveys_groups}}';
    }

    /** @inheritdoc */
    public function primaryKey()
    {
        return 'gsid';
    }

    /**
     * @inheritdoc
     * Set public for default group (gsid == 1)
     */
    protected function afterFind()
    {
        parent::afterFind();
        if ($this->gsid == 1) {
            $this->alwaysavailable = 1;
        }
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules()
    {
        // NOTE: you should only define rules for those attributes that
        // will receive user inputs.
        return array(
            array('name, sortorder, created_by, title', 'required'),
            array('sortorder, owner_id, parent_id, created_by', 'numerical', 'integerOnly' => true),
            array('name', 'length', 'max' => 45),
            array('name', 'match', 'pattern' => '/^[A-Za-z0-9_\.]+$/u','message' => gT('Group code can contain only alphanumeric character, underscore or dot. Spaces are not allowed.')),
            array('title', 'length', 'max' => 100),
            array('alwaysavailable', 'boolean'),
            array('description, created, modified', 'safe'),
            array('parent_id', 'in', 'range' => array_keys(self::getSurveyGroupsList()), 'allowEmpty' => true, 'message' => gT("You are not allowed to set this group as parent")),
            // The following rule is used by search().
            // @todo Please remove those attributes that should not be searched.
            array('gsid, name, title, description, owner_id, parent_id, created, modified, created_by', 'safe', 'on' => 'search'),
            array('name', 'unsafe' , 'on' => ['update']),
        );
    }

    /**
     * @return array relational rules.
     */
    public function relations()
    {
        // NOTE: you may need to adjust the relation name and the related
        // class name for the relations automatically generated below.
        return array(
            'parentgroup' => array(self::BELONGS_TO, 'SurveysGroups', array('parent_id' => 'gsid'), 'together' => true),
            'owner'       => array(self::BELONGS_TO, 'User', 'owner_id', 'together' => true),
        );
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return array(
            'gsid'              => gT('ID'),
            'name'              => gT('Code'),
            'title'             => gT('Title'),
            'description'       => gT('Description'),
            'sortorder'         => gT('Sort order'),
            'owner_id'          => gT('Owner'),
            'parent_id'         => gT('Parent group'),
            'alwaysavailable'   => gT('Always available'),
            'created'           => gT('Created on'),
            'modified'          => gT('Modified on'),
            'created_by'        => gT('Created by'),
        );
    }

    /**
     * Returns Columns for grid view
     * @param array
     **/
    public function getColumns()
    {
        return array(

                array(
                    'id' => 'gsid',
                    'class' => 'CCheckBoxColumn',
                    'selectableRows' => '100',
                    'htmlOptions' => ['class' => 'ls-sticky-column'],
                ),
                array(
                    'header' => gT('Survey group ID'),
                    'name' => 'gsid',
                    'value' => '$data->gsid',
                    'htmlOptions' => ['class' => 'has-link'],
                ),


                array(
                    'header' => gT('Code'),
                    'name' => 'name',
                    'value' => '$data->name',
                    'htmlOptions' => ['class' => 'has-link'],
                ),

                array(
                    'header' => gT('Title'),
                    'name' => 'title',
                    'value' => '$data->title',
                    'htmlOptions' => ['class' => 'has-link'],
                ),

                array(
                    'header' => gT('Description'),
                    'name' => 'description',
                    'value' => '$data->description',
                    'htmlOptions' => ['class' => 'has-link'],
                ),

                array(
                    'header' => gT('Parent group'),
                    'name' => 'parent',
                    'value' => '$data->parentTitle',
                    'htmlOptions' => ['class' => 'has-link'],
                ),

                array(
                    'header' => gT('Available'),
                    'name' => 'alwaysavailable',
                    'value' => '$data->alwaysavailable',
                    'htmlOptions' => ['class' => 'has-link'],
                ),

                array(
                    'header' => gT('Owner'),
                    'name' => 'owner',
                    'value' => '$data->owner->users_name',
                    'htmlOptions' => ['class' => 'has-link'],
                ),

                array(
                    'header' => gT('Order'),
                    'name' => 'sortorder',
                    'value' => '$data->sortorder',
                    'htmlOptions' => ['class' => 'has-link'],
                ),
                array(
                    'header' => gT('Action'),
                    'name' => 'actions',
                    'type' => 'raw',
                    'value' => '$data->buttons',
                    'headerHtmlOptions' => ['class' => 'ls-sticky-column'],
                    'htmlOptions'       => ['class' => 'text-center ls-sticky-column'],
                ),
            );
    }

    /**
     * Retrieve if current user have update rights on this SurveysGroups
     * Used for buttons
     * @return boolean
     */
    public function getHasViewSurveyGroupRight()
    {
        return $this->hasPermission('group', 'read');
    }

    /**
     * Retrieves a list of models based on the current search/filter conditions.
     *
     * Typical usecase:
     * - Initialize the model fields with values from filter form.
     * - Execute this method to get CActiveDataProvider instance which will filter
     * models according to data in model fields.
     * - Pass data provider to CGridView, CListView or any similar widget.
     *
     * @return CActiveDataProvider the data provider that can return the models
     * based on the search/filter conditions.
     */
    public function search()
    {
        // @todo Please modify the following code to remove attributes that should not be searched.
        $pageSize = Yii::app()->user->getState('pageSize', Yii::app()->params['defaultPageSize']);
        $criteria = new LSDbCriteria();

        $criteria->select = array('DISTINCT t.*');

        $criteria->compare('t.gsid', $this->gsid);
        $criteria->compare('t.name', $this->name, true);
        $criteria->compare('t.title', $this->title, true);
        $criteria->compare('t.description', $this->description, true);
        $criteria->compare('t.sortorder', $this->sortorder);
        $criteria->compare('t.owner_id', $this->owner_id);
        $criteria->compare('t.parent_id', $this->parent_id);
        $criteria->compare('t.created', $this->created, true);
        $criteria->compare('t.modified', $this->modified, true);
        $criteria->compare('t.created_by', $this->created_by);

        // Permission
        $criteriaPerm = self::getPermissionCriteria();
        $criteria->mergeWith($criteriaPerm, 'AND');

        $dataProvider = new CActiveDataProvider($this, array(
            'criteria' => $criteria,
            'pagination' => array(
                'pageSize' => $pageSize
            )
        ));


        return $dataProvider;
    }

    public function getParentTitle()
    {
        // "(gsid: ".$data->parent_id.")"." ".$data->parentgroup->title,
        if (empty($this->parent_id)) {
            return "";
        } else {
            return $this->parentgroup->title;
        }
    }

    /**
     * Returns true if survey group has surveys
     * @return boolean
     */
    public function getHasSurveys()
    {
        $nbSurvey = Survey::model()->countByAttributes(array("gsid" => $this->gsid));
        return $nbSurvey > 0;
    }

    /**
     * Returns true if survey group has child survey groups
     * @return boolean
     */
    public function getHasChildGroups()
    {
        $nbSurvey = SurveysGroups::model()->countByAttributes(array("parent_id" => $this->gsid));
        return $nbSurvey > 0;
    }


    public function getAllParents($bOnlyGsid = false)
    {
        $aParents = array();
        $oRSurveyGroup = $this;
        while (!empty($oRSurveyGroup->parent_id)) {
            $oRSurveyGroup =  SurveysGroups::model()->findByPk($oRSurveyGroup->parent_id);
            $aParents[] = ($bOnlyGsid) ? $oRSurveyGroup->gsid : $oRSurveyGroup;
        }

        return $aParents;
    }

    /**
     * Returns the actions for gridview
     * @return string
     */
    public function getButtons()
    {
        $deleteUrl = App()->createUrl("admin/surveysgroups/sa/delete", array("id" => $this->gsid));
        $editUrl = App()->createUrl("admin/surveysgroups/sa/update", array("id" => $this->gsid));
        $surveySettingsUrl = App()->createUrl("admin/surveysgroups/sa/surveysettings", array("id" => $this->gsid));
        $permissionUrl = App()->createUrl("surveysGroupsPermission/index", array("id" => $this->gsid));
        $permissions = [
            'group_read'          => $this->hasPermission('group', 'read'),
            'permission_read'     => $this->hasPermission('permission', 'read'),
            'surveysettings_read' => $this->hasPermission('surveysettings', 'read'),
            'group_delete'        => $this->gsid != 1 && !$this->hasSurveys && $this->hasPermission('group', 'delete')
        ];
        $dropdownItems = [];
        $dropdownItems[] = [
            'title'            => gT('Edit survey group'),
            'url'              => $editUrl,
            'iconClass'        => 'ri-pencil-fill',
            'enabledCondition' =>
                $permissions['group_read'],
        ];
        $dropdownItems[] = [
            'title'            => gT('Permission'),
            'url'              => $permissionUrl,
            'iconClass'        => 'ri-lock-fill',
            'enabledCondition' =>
                $permissions['permission_read'],
        ];
        $dropdownItems[] = [
            'title'            => gT('Survey settings'),
            'url'              => $surveySettingsUrl,
            'iconClass'        => 'ri-settings-5-fill',
            'enabledCondition' =>
                $permissions['surveysettings_read'],
        ];
        $dropdownItems[] = [
            'title'            => gT('Delete survey group'),
            'url'              => $deleteUrl,
            'iconClass'        => 'ri-delete-bin-fill text-danger',
            'enabledCondition' =>
                $permissions['group_delete'],
            'linkAttributes'   => [
                'data-bs-toggle' => "modal",
                'data-post-url'  => $deleteUrl,
                'data-message'   => gT('Do you want to continue?'),
                'data-bs-target' => "#confirmation-modal"
            ]
        ];

        return App()->getController()->widget('ext.admin.grid.GridActionsWidget.GridActionsWidget', ['dropdownItems' => $dropdownItems], true);
    }

    /**
     * Get the group list for current user
     * @return array
     */
    public static function getSurveyGroupsList()
    {
        $aSurveyList = [];
        $criteria = new CDbCriteria();
        $criteriaPerm = self::getPermissionCriteria();
        $criteria->mergeWith($criteriaPerm, 'AND');
        $criteria->order = 'title ASC';
        $oSurveyGroups = self::model()->findAll($criteria);

        foreach ($oSurveyGroups as $oSurveyGroup) {
            $aSurveyList[$oSurveyGroup->gsid] = $oSurveyGroup->title;
        }

        return $aSurveyList;
    }

    public function getNextOrderPosition()
    {
        $oSurveysGroups = SurveysGroups::model()->findAll();
        return count($oSurveysGroups) + 1;
    }

    public function getParentGroupOptions($gsid = null)
    {
        $criteria = new CDbCriteria();
        if (!empty($gsid)) {
            $criteria->compare("t.gsid", '<>' . $gsid);
        }
        // Permission
        $criteriaPerm = self::getPermissionCriteria();
        $criteria->mergeWith($criteriaPerm, 'AND');
        if ($gsid && $this->parent_id) {
            /* If gsid is set : be sure to add current parent */
            $criteria->compare("t.gsid", $this->parent_id, false, 'OR');
        }
        $oSurveysGroups = SurveysGroups::model()->findAll($criteria);
        $options = [
            '' => gT('No parent group')
        ];

        foreach ($oSurveysGroups as $oSurveysGroup) {
            //$options[] = "<option value='".$oSurveymenu->id."'>".$oSurveymenu->title."</option>";

            $aParentsGsid = $oSurveysGroup->getAllParents(true);

            if (! in_array($this->gsid, $aParentsGsid)) {
                $options['' . ($oSurveysGroup->gsid) . ''] = '(' . $oSurveysGroup->name . ') ' . $oSurveysGroup->title;
            }
        }
        //return join('\n',$options);
        return $options;
    }

    /**
     * Returns the static model of the specified AR class.
     * Please note that you should have this exact method in all your CActiveRecord descendants!
     * @param string $className active record class name.
     * @return SurveysGroups the static model class
     */
    public static function model($className = __CLASS__)
    {
        /** @var self $model */
        $model = parent::model($className);
        return $model;
    }

    /**
     * get criteria from Permission
     * @return CDbCriteria
     */
    protected static function getPermissionCriteria()
    {
        $criteriaPerm = new CDbCriteria();
        if (!Permission::model()->hasGlobalPermission("surveys", 'read') || !Permission::model()->hasGlobalPermission("surveysgroups", 'read')) {
            $userid = App()->getCurrentUserId();
            /* owner of surveygroup */
            $criteriaPerm->compare('t.owner_id', $userid, false);
            /* Simple permission on SurveysGroup inside a group */
            $criteriaPerm->mergeWith(array(
                'join' => "LEFT JOIN {{permissions}} AS permissions ON (permissions.entity_id = t.gsid AND permissions.permission='group' AND permissions.entity='surveysgroups' AND permissions.uid='" . $userid . "') ",
            ));
            $criteriaPerm->compare('permissions.read_p', '1', false, 'OR');
            /* Permission on Survey inside a group */
            $criteriaPerm->mergeWith(array(
                'join' => "LEFT JOIN {{surveys}} AS surveys ON (surveys.gsid = t.gsid)
                        LEFT JOIN {{permissions}} AS surveypermissions ON (surveypermissions.entity_id = surveys.sid AND surveypermissions.permission='survey' AND surveypermissions.entity='survey' AND surveypermissions.uid='" . $userid . "') ",
            ));
            $criteriaPerm->compare('surveys.owner_id', $userid, false, 'OR');
            $criteriaPerm->compare('surveypermissions.read_p', '1', false, 'OR');
            /* default survey group is always avaliable */
            $criteriaPerm->compare('t.gsid', '1', false, 'OR');
            /* survey group set as avaiable */
            $criteriaPerm->compare('t.alwaysavailable', '1', false, 'OR'); // Is public
        }
        return $criteriaPerm;
    }

    /**
     * Get Permission data for SurveysGroup
     * @return array
     */
    public static function getPermissionData()
    {
        $aPermission = array(
            'group' => array(
                'create' => false,
                'read' => true, /* Minimal : forced to true when edit */
                'update' => true,
                'delete' => true,
                'import' => false,
                'export' => false,
                'title' => gT("Group"),
                'description' => gT("Permission to update name/description of this group or to delete this group. Read permission is used to give access to this group."),
                'img' => ' ri-file-edit-line',
            ),
            'surveysettings' => array(
                'create' => false, /* always exist as inherit when group was created */
                'read' => true,
                'update' => true,
                'delete' => false, /* always exist as inherit when group was created */
                'import' => false,
                'export' => false,
                'title' => gT("Survey settings"),
                'description' => gT("Permission to update survey settings for this group"),
                'img' => ' ri-file-edit-line',
            ),
            'permission' => array(
                'create' => true, /* allowed to add new users or group */
                'read' => true,
                'update' => true,
                'delete' => true, /* update ? */
                'import' => false,
                'export' => false,
                'title' => gT("Survey group security"),
                'description' => gT("Permission to modify survey group security settings"),
                'img' => ' ri-shield-check-fill',
            ),
        );
        return $aPermission;
    }

    /**
     * @inheritdoc
     */
    public static function getMinimalPermissionRead()
    {
        return 'group';
    }

    /**
     * Get the owner id of this Survey group
     * Used for Permission
     * @return integer
     */
    public function getOwnerId()
    {
        return $this->owner_id;
    }

    /**
     * @inheritdoc
     */
    public function hasPermission($sPermission, $sCRUD = 'read', $iUserID = null)
    {
        /* If have global : return true */
        if (Permission::model()->hasPermission(0, 'global', 'surveysgroups', $sCRUD, $iUserID)) {
            return true;
        }
        /* Specific need gsid */
        if (!$this->gsid) {
            return false;
        }
        /* Finally : return specific one */
        return Permission::model()->hasPermission($this->gsid, 'surveysgroups', $sPermission, $sCRUD, $iUserID);
    }

    /**
     * Returns an available code based on the current group count.
     * @return string
     */
    public static function getNewCode()
    {
        $attempts = 0;
        $surveyGroupCount = self::model()->count();
        $groupNumber = $surveyGroupCount + 1;
        $groupCode = "SG" . str_pad($groupNumber, 2, '0', STR_PAD_LEFT);
        while (self::model()->countByAttributes(['name' => $groupCode]) > 0) {
            $attempts++;
            $groupNumber++;
            $groupCode = "SG" . str_pad($groupNumber, 2, '0', STR_PAD_LEFT);
            // We only try a number of times, based on the record count.
            if ($attempts > $surveyGroupCount + 1) {
                throw new \Exception("Unable to get a valid survey group code after " . ($surveyGroupCount + 1) . " attempts");
            }
        }
        return $groupCode;
    }
}