Skip to content

Commit

Permalink
New feature #13513 : allow plugins to add expresssion manager function
Browse files Browse the repository at this point in the history
  • Loading branch information
Shnoulle committed May 30, 2018
1 parent 6f561be commit 2a6f8fd
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 23 deletions.
3 changes: 3 additions & 0 deletions application/controllers/admin/expressions.php
Expand Up @@ -45,6 +45,7 @@ function index()

App()->getClientScript()->registerScriptFile(App()->getConfig('generalscripts').'survey_runtime.js');
App()->getClientScript()->registerScriptFile(App()->getConfig('generalscripts').'/expressions/em_javascript.js');
App()->getClientScript()->registerPackage('expression-extend');
$this->_printOnLoad(Yii::app()->request->getQuery('sa', 'index'));
$aData['pagetitle'] = "ExpressionManager: {$aData['sa']}";
$aData['subaction'] = $this->_printTitle($aData['sa']);
Expand Down Expand Up @@ -128,6 +129,7 @@ public function survey_logic_file()
App()->getClientScript()->registerPackage('decimal');
App()->getClientScript()->registerScriptFile('SCRIPT_PATH', 'survey_runtime.js');
App()->getClientScript()->registerScriptFile('SCRIPT_PATH', '/expressions/em_javascript.js');
App()->getClientScript()->registerPackage('expression-extend');
App()->getClientScript()->registerCssFile(Yii::app()->getConfig('publicstyleurl').'expressionlogicfile.css');

SetSurveyLanguage($sid, $language);
Expand Down Expand Up @@ -172,6 +174,7 @@ public function survey_logic_form()
App()->getClientScript()->registerPackage('decimal');
App()->getClientScript()->registerScriptFile('SCRIPT_PATH', 'survey_runtime.js');
App()->getClientScript()->registerScriptFile('SCRIPT_PATH', '/expressions/em_javascript.js');
App()->getClientScript()->registerPackage('expression-extend');


$this->_renderWrappedTemplate('expressions', 'test/survey_logic_form', $aData);
Expand Down
50 changes: 28 additions & 22 deletions application/helpers/expressions/em_core_helper.php
Expand Up @@ -252,6 +252,24 @@ function __construct()
}
}

/**
* Since this class can be get by session, need to add a call the «start» event manually
* @return void
*/
public function ExpressionManagerStartEvent()
{
$event = new \LimeSurvey\PluginManager\PluginEvent('newValidFunctions');
$result = App()->getPluginManager()->dispatchEvent($event);
$newValidFunctions = (array) $result->get('functions');
$newPackages = (array) $result->get('packages'); // package added to expression-extend['depends'] : maybe don't add it in event, but add an helper ?
$this->RegisterFunctions($newValidFunctions); // No validation : plugin dev can break all easily
foreach($newPackages as $name => $package) {
Yii::app()->clientScript->addPackage($name,$package);
}
Yii::app()->clientScript->addPackage('expression-extend',array(
'depends' => array_keys($newPackages)
));
}
/**
* Add an error to the error log
*
Expand Down Expand Up @@ -687,7 +705,6 @@ private function RDP_EvaluateExpressions()
if (!$evalStatus) {
return false;
}

while (++$this->RDP_pos < $this->RDP_count) {
$token = $this->RDP_tokens[$this->RDP_pos];
if ($token[2] == 'RP') {
Expand Down Expand Up @@ -1817,10 +1834,11 @@ private function RDP_RunFunction($funcNameToken, $params)
if (!$this->RDP_isValidFunction($name)) {
return false;
}

$func = $this->RDP_ValidFunctions[$name];
$funcName = $func[0];
$result = 1; // default value for $this->RDP_onlyparse
if (function_exists($funcName)) {
if (is_callable($funcName)) {
$numArgsAllowed = array_slice($func, 5); // get array of allowable argument counts from end of $func
$argsPassed = is_array($params) ? count($params) : 0;

Expand All @@ -1839,7 +1857,7 @@ private function RDP_RunFunction($funcNameToken, $params)
$result = call_user_func_array('sprintf', $params);
break;
default:
$result = $funcName($params);
$result = call_user_func($funcName,$params);
break;
}
}
Expand All @@ -1848,7 +1866,7 @@ private function RDP_RunFunction($funcNameToken, $params)
switch ($argsPassed) {
case 0:
if (!$this->RDP_onlyparse) {
$result = $funcName();
$result = call_user_func($funcName);
}
break;
case 1:
Expand All @@ -1870,7 +1888,7 @@ private function RDP_RunFunction($funcNameToken, $params)
}
break;
default:
$result = $funcName($params[0]);
$result = call_user_func($funcName,$params[0]);
break;
}
}
Expand All @@ -1886,33 +1904,20 @@ private function RDP_RunFunction($funcNameToken, $params)
}
break;
default:
$result = $funcName($params[0], $params[1]);
$result = call_user_func($funcName,[$params[0], $params[1]]);
break;
}
}
break;
case 3:
if (!$this->RDP_onlyparse) {
$result = $funcName($params[0], $params[1], $params[2]);
$result = call_user_func($funcName,[$params[0], $params[1], $params[2]]);
}
break;
case 4:
if (!$this->RDP_onlyparse) {
$result = $funcName($params[0], $params[1], $params[2], $params[3]);
}
break;
case 5:
if (!$this->RDP_onlyparse) {
$result = $funcName($params[0], $params[1], $params[2], $params[3], $params[4]);
}
break;
case 6:
default:
if (!$this->RDP_onlyparse) {
$result = $funcName($params[0], $params[1], $params[2], $params[3], $params[4], $params[5]);
$result = call_user_func($funcName,$params);
}
break;
default:
$this->RDP_AddError(sprintf(self::gT("Unsupported number of arguments: %s"), $argsPassed), $funcNameToken);
return false;
}

Expand All @@ -1922,6 +1927,7 @@ private function RDP_RunFunction($funcNameToken, $params)
return false;
}
if (function_exists("geterrors_".$funcName)) {
/* @todo allow adding it for plugin , if it work …*/
if ($sError = call_user_func_array("geterrors_".$funcName, $params)) {
$this->RDP_AddError($sError, $funcNameToken);
return false;
Expand Down
5 changes: 4 additions & 1 deletion application/helpers/expressions/em_manager_helper.php
Expand Up @@ -669,6 +669,7 @@ private function __construct()
{
self::$instance =& $this;
$this->em = new ExpressionManager();
$this->em->ExpressionManagerStartEvent();
if (!isset($_SESSION['LEMlang'])) {
$_SESSION['LEMlang'] = 'en'; // so that there is a default
}
Expand All @@ -689,6 +690,8 @@ public static function &singleton()
else if (!isset(self::$instance)) {
if (isset($_SESSION['LEMsingleton'])) {
self::$instance = unserialize($_SESSION['LEMsingleton']);
/* Since we get it via session, need to launch core event again */
self::$instance->em->ExpressionManagerStartEvent();
}
else {
$c = __CLASS__;
Expand Down Expand Up @@ -4330,7 +4333,6 @@ public function setVariableAndTokenMappingsForExpressionManager($surveyid,$force
usort($this->questionSeq2relevance,'cmpQuestionSeq');
$this->numQuestions = count($this->questionSeq2relevance);
$this->numGroups = count($this->groupSeqInfo);

return true;
}

Expand Down Expand Up @@ -7239,6 +7241,7 @@ public static function FinishProcessPublicPage()
$LEM->pageRelevanceInfo[] = $LEM->groupRelevanceInfo;
$aScriptsAndHiddenInputs = self::GetRelevanceAndTailoringJavaScript(true);
$sScripts = implode('', $aScriptsAndHiddenInputs['scripts']);
App()->getClientScript()->registerPackage('expression-extend');
Yii::app()->clientScript->registerScript('lemscripts', $sScripts, CClientScript::POS_BEGIN);
$sHiddenInputs = implode('', $aScriptsAndHiddenInputs['inputs']);
Yii::app()->clientScript->registerScript('triggerEmRelevance', "triggerEmRelevance();", CClientScript::POS_END);
Expand Down
3 changes: 3 additions & 0 deletions plugins/Demo/demoAddEmFunction/assets/demoAddEmFunction.js
@@ -0,0 +1,3 @@
function sayHello(message) {
return "Hello " + message;
}
41 changes: 41 additions & 0 deletions plugins/Demo/demoAddEmFunction/demoAddEmFunction.php
@@ -0,0 +1,41 @@
<?php
/**
* Example plugin that add a simple function
*/
class demoAddEmFunction extends PluginBase
{
static protected $description = 'Demo: adding a new function';
static protected $name = 'demoAddEmFunction';

public function init()
{
$this->subscribe('newValidFunctions');
}

public function newValidFunctions()
{
Yii::setPathOfAlias(get_class($this),dirname(__FILE__));
//~ Yii::import(get_class($this).".exampleFunctions");
$newFunctions = array(
'sayHello' => array(
'\demoAddEmFunction\exampleFunctions::sayHello', // PHP function, no need Class if function is directly added here
'sayHello', // Javascript function
$this->gT("Say hello"), // Description for admin
'string sayHello(string)', // Extra description
'https://www.limesurvey.org', // Help url
1, // Number of argument (time to make a good description of EM …
),
);
$this->getEvent()->append('functions', $newFunctions);
/* For the js file : maybe add a helper on parent ? */
$newPackage = array(
'demoAddEmFunction'=> array(
//~ 'devBaseUrl' => '/plugins/'.get_class($this)."/assets",
'basePath' => get_class($this).".assets",
// Can be an external url with baseUrl
'js' => array(get_class($this).".js"),
),
);
$this->getEvent()->append('packages', $newPackage);
}
}
12 changes: 12 additions & 0 deletions plugins/Demo/demoAddEmFunction/exampleFunctions.php
@@ -0,0 +1,12 @@
<?php
/**
* This file is part of reloadAnyResponse plugin
*/
namespace demoAddEmFunction;
class exampleFunctions
{
public static function sayHello($message)
{
return "Hello ".$message;
}
}

0 comments on commit 2a6f8fd

Please sign in to comment.