addScriptToQuestion.php 6.28 KB
Newer Older
1 2 3 4 5
<?php
/**
 * Allow to add script to question.
 *
 * @author Denis Chenu <denis@sondages.pro>
6
 * @copyright 2016-2018 Denis Chenu <http://www.sondages.pro>
Chenu Denis's avatar
Chenu Denis committed
7
 * @license AGPL v3
8
 * @version 2.3.1
9 10
 *
 * This program is free software: you can redistribute it and/or modify
Chenu Denis's avatar
Chenu Denis committed
11
 * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
12 13 14 15 16 17 18 19
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */
20
class addScriptToQuestion extends PluginBase
21 22 23 24 25
{

  static protected $name = 'addScriptToQuestion';
  static protected $description = 'Allow to add easily script to question.';

26 27 28
  protected $storage = 'DbStorage';
  protected $settings = array(
      'scriptPositionAvailable'=>array(
29
          'type'=>'boolean',
30
          'label' => 'Show the scriptPosition attribute',
31 32 33 34 35 36 37 38 39 40 41 42 43
          'default' => 0,
      ),
      'scriptPositionDefault'=>array(
          'type'=>'select',
          'label' => 'Position for the script',
          'options'=>array(
            CClientScript::POS_HEAD=>"The script is inserted in the head section right before the title element (POS_HEAD).",
            CClientScript::POS_BEGIN=>"The script is inserted at the beginning of the body section (POS_BEGIN).",
            CClientScript::POS_END=>"The script is inserted at the end of the body section (POS_END).",
            CClientScript::POS_LOAD=>"the script is inserted in the window.onload() function (POS_LOAD).",
            CClientScript::POS_READY=>"the script is inserted in the jQuery's ready function (POS_READY).",
          ),
          'default'=>CClientScript::POS_END, /* This is really the best solution */
44 45 46 47 48 49 50 51 52 53 54
      ),
  );

  /**
  * Add function to be used in beforeQuestionRender event and to attriubute
  */
  public function init()
  {
    $this->subscribe('beforeQuestionRender','addScript');
    $this->subscribe('newQuestionAttributes','addScriptAttribute');
  }
55

56
  /**
57
   * Add the script when question is rendered
58 59
   * Add QID and SGQ replacement forced (because it's before this was added by core
   */
60 61 62 63
  public function addScript()
  {
    $oEvent=$this->getEvent();
    $aAttributes=QuestionAttribute::model()->getQuestionAttributes($oEvent->get('qid'));
64
    if(isset($aAttributes['javascript']) && trim($aAttributes['javascript']) && $aAttributes['scriptActivate'] == 1){
65 66
      $aReplacement=array(
        'QID'=>$oEvent->get('qid'),
67
        'GID'=>$oEvent->get('gid'),
Chenu Denis's avatar
Chenu Denis committed
68
        'SGQ'=>$oEvent->get('surveyId')."X".$oEvent->get('gid')."X".$oEvent->get('qid'),
69
      );
70
      if(floatval(Yii::app()->getConfig('versionnumber')) >=3) {
71 72 73 74
        $script=LimeExpressionManager::ProcessString($aAttributes['javascript'], $oEvent->get('qid'), $aReplacement, 2, 0, false, false, true);
      } else {
        $script=LimeExpressionManager::ProcessString($aAttributes['javascript'], $oEvent->get('qid'), $aReplacement, false, 2, 0, false, false, true);
      }
75
      $aAttributes['scriptPosition']=isset($aAttributes['scriptPosition']) ? $aAttributes['scriptPosition'] : CClientScript::POS_END;
76 77 78 79
      App()->getClientScript()->registerScript("scriptAttribute{$oEvent->get('qid')}",$script,$aAttributes['scriptPosition']);
    }
  }

80
  /**
81
   * The attribute, use readonly for 3.X version
82
   */
83 84
  public function addScriptAttribute()
  {
Chenu Denis's avatar
Chenu Denis committed
85
    $readonly = Yii::app()->getConfig('filterxsshtml') && !Permission::model()->hasGlobalPermission('superadmin', 'read');
86
    $scriptAttributes = array(
87 88
      'scriptActivate' => array(
        'types'     => '15ABCDEFGHIKLMNOPQRSTUWXYZ!:;|*', /* all question types */
89
        'category'  => gT('Script'),
90 91
        'sortorder' => 1,
        'inputtype' => 'switch',
92
        'readonly'=>$readonly,
93 94 95
        'caption'   => 'Activate script execution',
        'default'   => '1',
      ),
96 97 98
      'javascript'=>array(
        'types'=>'15ABCDEFGHIKLMNOPQRSTUWXYZ!:;|*', /* Whole question type */
        'category'=>gT('Script'), /* Workaround ? Tony Partner :)))) ? */
99
        'sortorder'=>1, /* Own category */
100
        'inputtype'=>'textarea',
101
        'default'=>'', /* not needed (it's already the default) */
102
        'expression'=>1,/* As static */
Chenu Denis's avatar
Chenu Denis committed
103 104 105
        'readonly'=>$readonly,
        'help'=>$this->gT("You don't have to add script tag, script is register by LimeSurvey. You can use expressions, this one is static (no update during run-time)."),
        'caption'=>$this->gT('Javascript for this question'),
106
      ),
107
    );
Chenu Denis's avatar
Chenu Denis committed
108
    if($this->get('scriptPositionAvailable',null,null,$this->settings['scriptPositionAvailable']['default']) && !$readonly){
109
      $scriptAttributes['scriptPosition']=array(
110 111 112 113 114
        'types'=>'15ABCDEFGHIKLMNOPQRSTUWXYZ!:;|*', /* Whole question type */
        'category'=>gT('Script'),
        'sortorder'=>1,
        'inputtype'=>'singleselect',
        'options'=>array(
Chenu Denis's avatar
Chenu Denis committed
115 116 117 118 119
          CClientScript::POS_HEAD=>$this->gT("The script is inserted in the head section right before the title element (POS_HEAD)."),
          CClientScript::POS_BEGIN=>$this->gT("The script is inserted at the beginning of the body section (POS_BEGIN)."),
          CClientScript::POS_END=>$this->gT("The script is inserted at the end of the body section (POS_END)."),
          CClientScript::POS_LOAD=>$this->gT("The script is inserted in the window.onload() function (POS_LOAD)."),
          CClientScript::POS_READY=>$this->gT("The script is inserted in the jQuery's ready function (POS_READY)."),
120
        ),
121
        'default'=>$this->get('scriptPositionDefault',null,null,$this->settings['scriptPositionDefault']['default']),
122
        'readonly'=>$readonly,
Chenu Denis's avatar
Chenu Denis committed
123 124
        'help'=>sprintf($this->gT('Set the position of the script, see <a href="%s">Yii manual</a>.'),'http://www.yiiframework.com/doc/api/1.1/CClientScript#registerScript-detail'),
        'caption'=>$this->gT('Position for the script'),
125 126
      );
    }
127 128 129 130

    if(method_exists($this->getEvent(),'append')) {
      $this->getEvent()->append('questionAttributes', $scriptAttributes);
    } else {
131 132 133 134
      $questionAttributes=(array)$this->event->get('questionAttributes');
      $questionAttributes=array_merge($questionAttributes,$scriptAttributes);
      $this->event->set('questionAttributes',$questionAttributes);
    }
135 136
  }
}