shogodev /
argilla
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | /** |
||
| 3 | * @author Sergey Glagolev <[email protected]> |
||
| 4 | * @link https://github.com/shogodev/argilla/ |
||
| 5 | * @copyright Copyright © 2003-2014 Shogo |
||
| 6 | * @license http://argilla.ru/LICENSE |
||
| 7 | * @package backend.widgets |
||
| 8 | * |
||
| 9 | * Examples: |
||
| 10 | * <pre> |
||
| 11 | * echo $form->relatedItemsRow($model, 'steps', array( |
||
| 12 | * 'position' => array('class' => 'span1'),
|
||
| 13 | * 'content' => array('class' => 'span8', 'label' => 'Текст'),
|
||
| 14 | * 'visible' => array('type' => 'checkbox'),
|
||
| 15 | * 'image' => array('tag' => 'image'),
|
||
| 16 | * 'coating_id' => array('tag' => 'dropdownlist', 'items' => CHtml::listData(BProductParamVariant::model()->findAllByAttributes(array('param_id' => self::COATING_ID)), 'id', 'name')),
|
||
| 17 | * 'value' => array('tag' => 'dropdownlist', 'defaultItem' => false, 'items' => array(1 => 'value 1', 2 => 'value 2'),
|
||
| 18 | * 'description' => array('type' => 'textarea'),
|
||
| 19 | * 'color' => array('tag' => 'color')
|
||
| 20 | * )); |
||
| 21 | * |
||
| 22 | * echo $form->relatedItemsRow($model, 'steps', array( |
||
| 23 | * 'content' => array('tag' => function($model, $options) use($form) {
|
||
| 24 | * $options['class'] = 'span10'; |
||
| 25 | * echo CHtml::textArea(Arr::cut($options, 'name'), Arr::cut($options, 'value'), $options); |
||
| 26 | * }), |
||
| 27 | * )); |
||
| 28 | * |
||
| 29 | * echo $form->relatedItemsRow($model, 'steps', array( |
||
| 30 | * 'sections' => array('tag' => function($model, $options) use($form) {
|
||
| 31 | * echo CHtml::dropDownList(Arr::cut($options, 'name'), Arr::cut($options, 'value'), CHtml::listData(Section::model()->findAll(), 'id', 'name'), $options); |
||
| 32 | * }), |
||
| 33 | * )); |
||
| 34 | * </pre> |
||
| 35 | */ |
||
| 36 | class RelatedItemsWidget extends CWidget |
||
| 37 | {
|
||
| 38 | /** |
||
| 39 | * @var BActiveRecord |
||
| 40 | */ |
||
| 41 | public $model; |
||
| 42 | |||
| 43 | public $relation; |
||
| 44 | |||
| 45 | public $attributes = array('name');
|
||
| 46 | |||
| 47 | protected $className; |
||
| 48 | |||
| 49 | public function run() |
||
| 50 | {
|
||
| 51 | if( !isset($this->model) ) |
||
| 52 | {
|
||
| 53 | throw new CHttpException(500, '"model" have to be set!'); |
||
| 54 | } |
||
| 55 | |||
| 56 | $this->className = $this->model->getActiveRelation($this->relation)->className; |
||
| 57 | |||
| 58 | $this->renderLabel(); |
||
| 59 | $this->renderElements(); |
||
| 60 | $this->renderCloneScript(); |
||
| 61 | } |
||
| 62 | |||
| 63 | protected function renderLabel() |
||
| 64 | {
|
||
| 65 | echo CHtml::openTag('th', array('class' => 'multi-list'));
|
||
| 66 | echo CHtml::tag('label', array(), $this->model->getAttributeLabel($this->relation));
|
||
| 67 | echo CHtml::tag('div', array(), CHtml::tag('span', array('class' => 'btn btn-info action', 'id' => 'add-item-btn-'.$this->relation), 'Добавить'));
|
||
| 68 | echo CHtml::closeTag('th');
|
||
| 69 | } |
||
| 70 | |||
| 71 | protected function renderElements() |
||
| 72 | {
|
||
| 73 | $element = new $this->className; |
||
| 74 | |||
| 75 | echo CHtml::openTag('td', array('class' => 'multi-list'));
|
||
| 76 | $this->renderHeader($element); |
||
| 77 | |||
| 78 | echo CHtml::openTag('ul', array('class' => 'multi-list-items'));
|
||
| 79 | $this->renderElement($element, array('id' => 'template', 'style' => 'display: none;'));
|
||
| 80 | |||
| 81 | foreach($this->model->{$this->relation} as $element)
|
||
| 82 | $this->renderElement($element); |
||
| 83 | |||
| 84 | echo CHtml::closeTag('ul');
|
||
| 85 | echo CHtml::closeTag('td');
|
||
| 86 | } |
||
| 87 | |||
| 88 | /** |
||
| 89 | * @param BActiveRecord $element |
||
| 90 | */ |
||
| 91 | protected function renderHeader($element) |
||
| 92 | {
|
||
| 93 | echo CHtml::openTag('ul', array('class' => 'multi-list-header clearfix'));
|
||
| 94 | foreach($this->attributes as $key => $attributeOptions) |
||
| 95 | {
|
||
| 96 | if( is_null($attributeOptions) ) |
||
| 97 | continue; |
||
| 98 | |||
| 99 | $name = is_array($attributeOptions) ? $key : $attributeOptions; |
||
| 100 | $label = Arr::cut($attributeOptions, 'label', $element->getAttributeLabel($name)); |
||
|
0 ignored issues
–
show
|
|||
| 101 | echo CHtml::tag('li', array('class' => 'multi-list-header-col'), $label, false);
|
||
| 102 | echo ' '; |
||
| 103 | } |
||
| 104 | |||
| 105 | echo CHtml::closeTag('ul');
|
||
| 106 | } |
||
| 107 | |||
| 108 | /** |
||
| 109 | * @param BActiveRecord $element |
||
| 110 | * @param array $htmlOptions |
||
| 111 | * |
||
| 112 | * @internal param null $id |
||
| 113 | */ |
||
| 114 | protected function renderElement(BActiveRecord $element, $htmlOptions = array()) |
||
| 115 | {
|
||
| 116 | $id = Arr::get($htmlOptions, 'id', $element->getPrimaryKey()); |
||
| 117 | $htmlOptions['id'] = get_class($element).'-'.$id; |
||
| 118 | |||
| 119 | echo CHtml::tag('li', $htmlOptions, false, false);
|
||
| 120 | |||
| 121 | foreach($this->attributes as $key => $attributeOptions) |
||
| 122 | {
|
||
| 123 | if( is_null($attributeOptions) ) |
||
| 124 | continue; |
||
| 125 | |||
| 126 | $attribute = is_array($attributeOptions) ? $key : $attributeOptions; |
||
| 127 | $tag = Arr::get($attributeOptions, 'tag', 'input'); |
||
| 128 | $type = Arr::get($attributeOptions, 'type', 'text'); |
||
| 129 | |||
| 130 | $options = Arr::get($attributeOptions, 'htmlOptions', array('class' => 'span4'));
|
||
| 131 | |||
| 132 | if( isset($attributeOptions['class']) ) |
||
| 133 | $options['class'] = $attributeOptions['class']; |
||
| 134 | |||
| 135 | $options['name'] = "{$this->className}[{$id}][{$attribute}]";
|
||
| 136 | $options['value'] = $element->$attribute; |
||
| 137 | |||
| 138 | if( is_string($tag) ) |
||
| 139 | {
|
||
| 140 | switch($tag) |
||
| 141 | {
|
||
| 142 | case 'image': |
||
| 143 | echo CHtml::openTag('span', array('style' => 'display: inline-block;'));
|
||
| 144 | echo CHtml::openTag('span', array('style' => 'display: inline-block; width: 24px; margin-right: 7px;'));
|
||
| 145 | echo CHtml::image($element->getImage($attribute), '', Arr::get($attributeOptions, 'imageOptions', array('style' => 'max-width: 24px; max-height: 24px;')));
|
||
| 146 | echo CHtml::closeTag('span');
|
||
| 147 | echo CHtml::fileField($options['name'], $options['value']); |
||
| 148 | echo CHtml::closeTag('span');
|
||
| 149 | break; |
||
| 150 | |||
| 151 | case 'dropdownlist': |
||
| 152 | $defaultItem = Arr::cut($attributeOptions, 'defaultItem', array('' => 'Не задано'));
|
||
|
0 ignored issues
–
show
Are you sure the assignment to
$defaultItem is correct as \Arr::cut($attributeOpti...> 'Не задано')) (which targets Arr::cut()) seems to always return null.
This check looks for function or method calls that always return null and whose return value is assigned to a variable. class A
{
function getObject()
{
return null;
}
}
$a = new A();
$object = $a->getObject();
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. Loading history...
|
|||
| 153 | $items = !empty($defaultItem) ? $defaultItem : array(); |
||
| 154 | $items = CMap::mergeArray($items, Arr::cut($attributeOptions, 'items', array())); |
||
| 155 | echo CHtml::dropDownList($options['name'], $options['value'], $items, $options); |
||
| 156 | break; |
||
| 157 | |||
| 158 | case 'textarea': |
||
| 159 | $options['class'] = isset($options['class']) ? $options['class'].' related-item-textarea' : ''; |
||
| 160 | echo CHtml::textArea($options['name'], $options['value'], $options); |
||
| 161 | break; |
||
| 162 | |||
| 163 | case 'color': |
||
| 164 | $options['type'] = 'color'; |
||
| 165 | $tag = 'input'; |
||
| 166 | $options['class'] = isset($options['class']) ? $options['class'].' input-color' : ''; |
||
| 167 | |||
| 168 | case 'input': |
||
| 169 | $options['type'] = Arr::get($options, 'type', $type); |
||
| 170 | |||
| 171 | if( $options['type'] == 'checkbox' ) |
||
| 172 | {
|
||
| 173 | $options['value'] = CheckBoxBehavior::CHECKED_VALUE; |
||
| 174 | if( !empty($element->$attribute) ) |
||
| 175 | $options['checked'] = 'checked'; |
||
| 176 | } |
||
| 177 | |||
| 178 | default: |
||
| 179 | echo CHtml::tag($tag, $options); |
||
| 180 | } |
||
| 181 | } |
||
| 182 | elseif( is_callable($tag) ) |
||
| 183 | {
|
||
| 184 | call_user_func_array($tag, array($element, $options)); |
||
| 185 | } |
||
| 186 | |||
| 187 | echo ' '; |
||
| 188 | } |
||
| 189 | |||
| 190 | $this->renderAjaxButton($id); |
||
| 191 | echo CHtml::closeTag('li');
|
||
| 192 | } |
||
| 193 | |||
| 194 | protected function renderAjaxButton($id) |
||
| 195 | {
|
||
| 196 | echo CHtml::ajaxLink('', $this->controller->createUrl('deleteRelated'),
|
||
| 197 | array( |
||
| 198 | 'type' => 'post', |
||
| 199 | 'data' => array('id' => $id, 'relation' => $this->relation),
|
||
| 200 | 'update' => '#'.$this->className.'-'.$id, |
||
| 201 | 'beforeSend' => "function(){return confirm('Вы действительно хотите удалить данный элемент?')}",
|
||
| 202 | 'error' => 'function(){alert("Невозможно удалить элемент!")}'),
|
||
| 203 | array( |
||
| 204 | 'class' => 'btn btn-alone delete', |
||
| 205 | 'rel' => 'tooltip', |
||
| 206 | 'data-original-title' => 'Удалить элемент' |
||
| 207 | ) |
||
| 208 | ); |
||
| 209 | } |
||
| 210 | |||
| 211 | protected function renderCloneScript() |
||
| 212 | {
|
||
| 213 | Yii::app()->clientScript->registerScript(__CLASS__.$this->relation, " |
||
| 214 | var className = '{$this->className}';
|
||
| 215 | var button = $('#add-item-btn-{$this->relation}');
|
||
| 216 | var itemsExp = '[name*=' + className + '\\\\[template\\\\]]'; |
||
| 217 | |||
| 218 | button.parents('tr').find(itemsExp).attr('disabled', 'disabled');
|
||
| 219 | |||
| 220 | $(button).on('click', function()
|
||
| 221 | {
|
||
| 222 | var tr = $(this).parents('tr');
|
||
| 223 | var template = tr.find('#' + className + '-template');
|
||
| 224 | var ul = tr.find('td ul.multi-list-items');
|
||
| 225 | var count = $(ul).find('li').length;
|
||
| 226 | var li = template.clone(); |
||
| 227 | var re = /(\w+)\[(\w+)\]\[(\w+)\]/; |
||
| 228 | |||
| 229 | $(li).find(itemsExp).each(function(){
|
||
| 230 | var name = $(this).attr('name').replace(re, '$1[new' + String(count) + '][$3]');
|
||
| 231 | $(this).attr('name', name);
|
||
| 232 | $(this).removeAttr('disabled');
|
||
| 233 | }); |
||
| 234 | |||
| 235 | li.show().removeAttr('id').find('.delete').remove();
|
||
| 236 | li.append('<a class=\"btn btn-alone delete\" rel=\"tooltip\" href=\"#\" data-original-title=\"Удалить вариант\">');
|
||
| 237 | $(li).find('a').on('click', function(e){e.preventDefault();$(this).parents('li').remove()});
|
||
| 238 | $(ul).append(li); |
||
| 239 | }); |
||
| 240 | |||
| 241 | var setHeaderSizes = function() {
|
||
| 242 | $('.multi-list-header li').each(function(index) {
|
||
| 243 | var width = $('ul.multi-list-items li:eq(1)').children().eq(index).outerWidth();
|
||
| 244 | $(this).width(width); |
||
| 245 | }); |
||
| 246 | }; |
||
| 247 | |||
| 248 | setHeaderSizes(); |
||
| 249 | |||
| 250 | $(window).on('resize', function() {
|
||
| 251 | setHeaderSizes() |
||
| 252 | });", CClientScript::POS_READY); |
||
| 253 | } |
||
| 254 | } |
This check looks for function or method calls that always return null and whose return value is assigned to a variable.
The method
getObject()can return nothing but null, so it makes no sense to assign that value to a variable.The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.