1: <?php
2:
3: declare(strict_types=1);
4:
5: namespace Atk4\Ui\Table\Column;
6:
7: use Atk4\Data\Field;
8: use Atk4\Data\Model;
9: use Atk4\Ui\HtmlTemplate;
10: use Atk4\Ui\Table;
11:
12: /**
13: * Implements Column helper for grid.
14: * Use
15: * new Link('https://yahoo.com?id={$id}');
16: * or
17: * new Link(['order', 'id' => 'id' ]);
18: * or
19: * new Link(['order', 'id' ]);
20: * or
21: * new Link([['order', 'x' => $myval], 'id']);.
22: */
23: class Link extends Table\Column
24: {
25: /**
26: * If $url is set up, we will use pattern-matching to fill-in any part of this
27: * with values of the model.
28: *
29: * @var string|HtmlTemplate
30: */
31: public $url;
32:
33: /**
34: * If string 'example', then will be passed to $app->url('example') along with any defined arguments.
35: * If set as array, then non-0 key/values will be also passed to the URL:
36: * $page = ['example', 'type' => '123'];.
37: *
38: * $url = $app->url(['example', 'type' => '123']);
39: *
40: * In addition to above "args" refer to values picked up from a current row.
41: *
42: * @var string|array<0|string, string|int|false>|null
43: */
44: public $page;
45:
46: /**
47: * When constructing a URL using 'page', this specifies list of values which will be added
48: * to the destination URL. For example if you set $args = ['document_id' => 'id'] then row value
49: * of ['id'] will be added to URL's property "document_id".
50: *
51: * For a full example:
52: * $page = ['example', 'type' => 'client'];
53: * $args = ['contact_id' => 'id'];
54: *
55: * Link URL will be "example.php?type=client&contact_id=4"
56: *
57: * You can also pass non-key arguments ['id', 'title'] and they will be added up
58: * as ?id=4&title=John%20Smith
59: *
60: * @var array<int|string, string>
61: */
62: public $args = [];
63:
64: /** @var bool use value as label of the link */
65: public $useLabel = true;
66:
67: /** @var string|null set element class. */
68: public $class;
69:
70: /** @var string|null Use icon as label of the link. */
71: public $icon;
72:
73: /**
74: * Set html5 target attribute in tag
75: * possible values: _blank | _parent | _self | _top | frame#name.
76: *
77: * @var string|null
78: */
79: public $target;
80:
81: /** @var bool add download in the tag to force download from the URL. */
82: public $forceDownload = false;
83:
84: /**
85: * @param string|array<0|string, string|int|false> $page
86: */
87: public function __construct($page = [], array $args = [], array $defaults = [])
88: {
89: if (is_array($page)) {
90: $defaults['page'] = $page;
91: } else {
92: $defaults['url'] = $page;
93: }
94:
95: $defaults['args'] = $args;
96:
97: parent::__construct($defaults);
98: }
99:
100: #[\Override]
101: protected function init(): void
102: {
103: parent::init();
104:
105: if (is_string($this->url)) {
106: $this->url = new HtmlTemplate($this->url);
107: }
108: if (is_string($this->page)) {
109: $this->page = [$this->page];
110: }
111: }
112:
113: #[\Override]
114: public function getDataCellTemplate(Field $field = null): string
115: {
116: $attr = ['href' => '{$c_' . $this->shortName . '}'];
117:
118: if ($this->forceDownload) {
119: $attr['download'] = 'true';
120: }
121:
122: if ($this->target) {
123: $attr['target'] = $this->target;
124: }
125:
126: $iconHtml = '';
127: if ($this->icon) {
128: $iconHtml = $this->getApp()->getTag('i', ['class' => $this->icon . ' icon'], '');
129: }
130:
131: $labelHtml = '';
132: if ($this->useLabel) {
133: $labelHtml = $field ? ('{$' . $field->shortName . '}') : '[Link]';
134: }
135:
136: if ($this->class) {
137: $attr['class'] = $this->class;
138: }
139:
140: return $this->getApp()->getTag('a', $attr, [$iconHtml, $labelHtml]);
141: }
142:
143: #[\Override]
144: public function getHtmlTags(Model $row, ?Field $field): array
145: {
146: if ($this->url) {
147: $rowValues = $this->getApp()->uiPersistence->typecastSaveRow($row, $row->get());
148:
149: return ['c_' . $this->shortName => $this->url->set($rowValues)->renderToHtml()];
150: }
151:
152: $page = $this->page ?? [];
153:
154: foreach ($this->args as $key => $val) {
155: if (is_int($key)) {
156: $key = $val;
157: }
158:
159: $page[$key] = $row->get($val);
160: }
161:
162: return ['c_' . $this->shortName => $this->table->url($page)];
163: }
164: }
165: