/** * Editor * * @param array $attr * @param array $item * * @return string */ function editor(array $attr, array $item) : string { if (!in_array('edit', $attr['actions'])) { return ''; } $item[$attr['id']] = $item[$attr['id']] ?? $attr['val']; $attr['opt'] = opt($attr); $attr['context'] = 'edit'; $attr['html']['id'] = html_id($attr, $item); $attr['html']['name'] = html_name($attr, $item); $attr['html']['data-type'] = $attr['type']; if ($attr['required'] && !ignorable($attr, $item)) { $attr['html']['required'] = true; } if (!empty($attr['multiple'])) { $attr['html']['multiple'] = true; } if (!empty($item['_error'][$attr['id']])) { $attr['html']['class'] = empty($attr['html']['class']) ? 'invalid' : $attr['html']['class'] . ' invalid'; } $html = ''; $callback = fqn('editor_' . $attr['type']); if (is_callable($callback)) { $html = $callback($attr, $item); } else { // @todo switch ($attr['frontend']) { case 'select': $html = editor_select($attr, $item); break; case 'checkbox': case 'radio': $html = editor_opt($attr, $item); break; case 'color': case 'email': case 'url': $html = editor_text($attr, $item); break; case 'number': case 'range': $html = editor_int($attr, $item); break; case 'date': case 'time': $html = editor_datetime($attr, $item); break; case 'file': $html = editor_file($attr, $item); break; case 'textarea': $html = editor_textarea($attr, $item); break; } } return $html ? html_label($attr, $item) . $html . html_message($attr, $item) : ''; }
/** * Saver * * @param array $attr * @param array $item * * @return bool */ function saver(array $attr, array &$item) : bool { $callback = fqn('saver_' . $attr['type']); if (is_callable($callback)) { return $callback($attr, $item); } // @todo if ($attr['frontend'] === 'file') { return saver_file($attr, $item); } return true; }
/** * Loader * * @param array $attr * @param array $item * * @return mixed */ function loader(array $attr, array $item) { $item[$attr['id']] = cast($attr, $item[$attr['id']] ?? null); $callback = fqn('loader_' . $attr['type']); if (is_callable($callback)) { return $callback($attr, $item); } // @todo if ($attr['backend'] === 'json') { return loader_json($attr, $item); } return $item[$attr['id']]; }
/** * Privilege data listener * * @param array $data * * @return void */ function listener_data_privilege(array &$data) : void { foreach ($data as $id => $item) { if (!empty($item['callback'])) { $data[$id]['callback'] = fqn($item['callback']); } } foreach (data('entity') as $eId => $entity) { foreach ($entity['actions'] as $action) { $data[$eId . '.' . $action] = ['name' => $entity['name'] . ' ' . ucwords($action), 'active' => true]; } } $data = data_order($data, ['sort' => 'asc', 'name' => 'asc']); }
/** * Viewer * * @param array $attr * @param array $item * * @return string */ function viewer(array $attr, array $item) : string { $attr['context'] = $attr['context'] ?? 'view'; if (!in_array($attr['context'], $attr['actions'])) { return ''; } $attr['opt'] = opt($attr); $callback = fqn('viewer_' . $attr['type']); if (is_callable($callback)) { return $callback($attr, $item); } // @todo if (in_array($attr['frontend'], ['checkbox', 'radio', 'select'])) { return viewer_opt($attr, $item); } return $item[$attr['id']] ? encode($item[$attr['id']]) : (string) $item[$attr['id']]; }
/** * Validator * * @param array $attr * @param array $item * * @return bool */ function validator(array $attr, array &$item) : bool { if (!in_array('edit', $attr['actions'])) { return true; } $item[$attr['id']] = cast($attr, $item[$attr['id']] ?? null); if ($item[$attr['id']] === null && !empty($attr['nullable'])) { return true; } $attr['opt'] = opt($attr); $valid = true; $callback = fqn('validator_' . $attr['type']); if (is_callable($callback)) { $valid = $callback($attr, $item); } else { // @todo switch ($attr['frontend']) { case 'checkbox': case 'radio': case 'select': $valid = validator_opt($attr, $item); break; case 'password': case 'textarea': $valid = validator_text($attr, $item); break; case 'date': case 'time': $valid = validator_datetime($attr, $item); break; case 'file': $valid = validator_file($attr, $item); break; } } return $valid && validator_uniq($attr, $item) && validator_required($attr, $item) && validator_boundary($attr, $item); }
/** * Delete entity * * @param string $eId * @param array $crit * @param array $opts * * @return bool */ function delete(string $eId, array $crit = [], array $opts = []) : bool { $entity = data('entity', $eId); $callback = fqn($entity['model'] . '_delete'); $success = []; $error = []; foreach (all($eId, $crit, $opts) as $id => $item) { if (empty($opts['system']) && !empty($item['system'])) { message(_('You must not delete system items! Therefore skipped Id %s', $id)); continue; } foreach (array_keys($item) as $uid) { if (isset($entity['attr'][$uid]) && !deleter($entity['attr'][$uid], $item)) { if (!empty($item['_error'][$uid])) { message($item['_error'][$uid]); } $error[] = $item['name']; continue 2; } } $trans = trans(function () use($eId, &$item, $callback, $entity) { event(['entity.preDelete', 'model.preDelete.' . $entity['model'], 'entity.preDelete.' . $eId], $item); if (!$callback($item)) { throw new RuntimeException(_('Could not delete %s', $item['_id'])); } event(['entity.postDelete', 'model.postDelete.' . $entity['model'], 'entity.postDelete.' . $eId], $item); }); if ($trans) { $success[] = $item['name']; } else { $error[] = $item['name']; } } if ($success) { message(_('Successfully deleted %s', implode(', ', $success))); } if ($error) { message(_('Could not delete %s', implode(', ', $error))); } return !$error; }
function convertUse($filepath, &$file) { if (!strpos($file, "\tuse ")) { return; } list($namespace, $table) = fqn($file); // Hardcode a couple of names if (strpos($filepath, 'Parser.php')) { $table['BuiltInFilters'] = 's9e\\TextFormatter\\Parser\\BuiltInFilters'; $table['Tag'] = 's9e\\TextFormatter\\Parser\\Tag'; } $file = preg_replace_callback('#^\\tuse ([^;]+);\\n*#m', function ($m) use($namespace, &$table) { $fqn = isset($table[$m[1]]) ? $table[$m[1]] : $namespace . '\\' . $m[1]; $path = __DIR__ . '/../../src' . str_replace('\\', DIRECTORY_SEPARATOR, substr($fqn, 17)) . '.php'; $path = str_replace('/../../src/Tests/', '/../../tests/', $path); if (!file_exists($path)) { die("Cannot find {$fqn} in {$path}\n"); } $file = file_get_contents($path); list(, $traitTable) = fqn($file); $table += $traitTable; preg_match('#\\n{\\n(.*)\\n}$#s', $file, $m); return $m[1] . "\n\n"; }, $file); if ($table) { $table = array_unique($table); sort($table); $file = preg_replace('#^use.*?;\\n\\n#ms', 'use ' . implode(";\nuse ", $table) . ";\n\n", $file); } }
/** * Attribute data * * @param array $data * * @return array * * @throws RuntimeException */ function data_attr(array $data) : array { // Check minimum requirements if (empty($data['id']) || empty($data['name']) || empty($data['type'])) { throw new RuntimeException(_('Attribute data does not meet the minimum requirements')); } // Clean up foreach (array_keys($data) as $key) { if (strpos($key, '_') === 0) { unset($data[$key]); } } // Type, Backend, Frontend $type = data('attr', $data['type']); if (!$type || empty($type['backend']) || empty($type['frontend'])) { throw new RuntimeException(_('Invalid type %s configured for attribute %s', $data['type'], $data['id'])); } $data = array_replace(data('skeleton', 'attr'), $type, $data); // Column if (!empty($data['virtual'])) { $data['col'] = null; } elseif (empty($data['col'])) { $data['col'] = $data['id']; } // Options callback if (!empty($data['opt'][0]) && is_string($data['opt'][0])) { $data['opt'][0] = fqn($data['opt'][0]); } return $data; }