1<?php 2 3namespace Elastica\Script; 4 5use Elastica\AbstractUpdateAction; 6use Elastica\Exception\InvalidException; 7 8/** 9 * Base class for Script object. 10 * 11 * Wherever scripting is supported in the Elasticsearch API, scripts can be referenced as "inline", "id" or "file". 12 * 13 * @author Nicolas Assing <nicolas.assing@gmail.com> 14 * @author Tobias Schultze <http://tobion.de> 15 * @author Martin Janser <martin.janser@liip.ch> 16 * 17 * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-scripting.html 18 */ 19abstract class AbstractScript extends AbstractUpdateAction 20{ 21 const LANG_MOUSTACHE = 'moustache'; 22 const LANG_EXPRESSION = 'expression'; 23 const LANG_PAINLESS = 'painless'; 24 25 /** 26 * @var string 27 */ 28 private $_lang; 29 30 /** 31 * Factory to create a script object from data structure (reverse toArray). 32 * 33 * @param string|array|AbstractScript $data 34 * 35 * @throws InvalidException 36 * 37 * @return Script|ScriptId 38 */ 39 public static function create($data) 40 { 41 if ($data instanceof self) { 42 return $data; 43 } 44 45 if (\is_array($data)) { 46 return self::_createFromArray($data); 47 } 48 49 if (\is_string($data)) { 50 $class = self::class === \get_called_class() ? Script::class : \get_called_class(); 51 52 return new $class($data); 53 } 54 55 throw new InvalidException('Failed to create script. Invalid data passed.'); 56 } 57 58 private static function _createFromArray(array $data) 59 { 60 $params = $data['script']['params'] ?? []; 61 $lang = $data['script']['lang'] ?? null; 62 63 if (!\is_array($params)) { 64 throw new InvalidException('Script params must be an array'); 65 } 66 67 if (isset($data['script']['source'])) { 68 return new Script( 69 $data['script']['source'], 70 $params, 71 $lang 72 ); 73 } 74 75 if (isset($data['script']['id'])) { 76 return new ScriptId( 77 $data['script']['id'], 78 $params, 79 $lang 80 ); 81 } 82 83 throw new InvalidException('Failed to create script. Invalid data passed.'); 84 } 85 86 /** 87 * @param array|null $params 88 * @param string|null $lang Script language, see constants 89 * @param string|null $documentId Document ID the script action should be performed on (only relevant in update context) 90 */ 91 public function __construct(array $params = null, string $lang = null, string $documentId = null) 92 { 93 if ($params) { 94 $this->setParams($params); 95 } 96 97 if (null !== $lang) { 98 $this->setLang($lang); 99 } 100 101 if (null !== $documentId) { 102 $this->setId($documentId); 103 } 104 } 105 106 /** 107 * @param string $lang 108 * 109 * @return $this 110 */ 111 public function setLang(string $lang): AbstractScript 112 { 113 $this->_lang = $lang; 114 115 return $this; 116 } 117 118 /** 119 * @return string|null 120 */ 121 public function getLang() 122 { 123 return $this->_lang; 124 } 125 126 /** 127 * Returns an array with the script type as key and the script content as value. 128 * 129 * @return array 130 */ 131 abstract protected function getScriptTypeArray(): array; 132 133 /** 134 * {@inheritdoc} 135 */ 136 public function toArray(): array 137 { 138 $array = $this->getScriptTypeArray(); 139 140 if (!empty($this->_params)) { 141 $array['params'] = $this->_convertArrayable($this->_params); 142 } 143 144 if (null !== $this->_lang) { 145 $array['lang'] = $this->_lang; 146 } 147 148 return ['script' => $array]; 149 } 150} 151