Add src files for CoreLibs composer all package

This commit is contained in:
Clemens Schwaighofer
2023-02-16 12:47:43 +09:00
commit cfcd601b3a
76 changed files with 25404 additions and 0 deletions

View File

@@ -0,0 +1,290 @@
<?php
/*
* elements for html output direct
*/
declare(strict_types=1);
namespace CoreLibs\Output\Form;
class Elements
{
/**
* print the date/time drop downs, used in any queue/send/insert at date/time place
*
* @param int $year year YYYY
* @param int $month month m
* @param int $day day d
* @param int $hour hour H
* @param int $min min i
* @param string $suffix additional info printed after the date time
* variable in the drop down
* also used for ID in the on change JS call
* @param int $min_steps default is 1 (minute), can set to anything,
* is used as sum up from 0
* @param bool $name_pos_back default false, if set to true,
* the name will be printend after the drop down
* and not before the drop down
* @return string HTML formated strings for drop down lists of date and time
*/
public static function printDateTime(
$year,
$month,
$day,
$hour,
$min,
string $suffix = '',
int $min_steps = 1,
bool $name_pos_back = false
) {
// if suffix given, add _ before
if ($suffix) {
$suffix = '_' . $suffix;
}
if ($min_steps < 1 || $min_steps > 59) {
$min_steps = 1;
}
$on_change_call = 'dt_list(\'' . $suffix . '\');';
// always be 1h ahead (for safety)
$timestamp = time() + 3600; // in seconds
// the max year is this year + 1;
$max_year = (int)date("Y", $timestamp) + 1;
// preset year, month, ...
$year = !$year ? date('Y', $timestamp) : $year;
$month = !$month ? date('m', $timestamp) : $month;
$day = !$day ? date('d', $timestamp) : $day;
$hour = !$hour ? date('H', $timestamp) : $hour;
$min = !$min ? date('i', $timestamp) : $min; // add to five min?
// max days in selected month
$days_in_month = date(
't',
strtotime($year . '-' . $month . '-' . $day . ' ' . $hour . ':' . $min . ':0') ?: null
);
$string = '';
// from now to ?
if ($name_pos_back === false) {
$string = 'Year ';
}
$string .= '<select id="year' . $suffix . '" name="year' . $suffix . '" onChange="' . $on_change_call . '">';
for ($i = date("Y"); $i <= $max_year; $i++) {
$string .= '<option value="' . $i . '" ' . ($year == $i ? 'selected' : '') . '>' . $i . '</option>';
}
$string .= '</select> ';
if ($name_pos_back === true) {
$string .= 'Year ';
}
if ($name_pos_back === false) {
$string .= 'Month ';
}
$string .= '<select id="month' . $suffix . '" name="month' . $suffix . '" onChange="' . $on_change_call . '">';
for ($i = 1; $i <= 12; $i++) {
$string .= '<option value="' . ($i < 10 ? '0' . $i : $i) . '" '
. ($month == $i ? 'selected' : '') . '>' . $i . '</option>';
}
$string .= '</select> ';
if ($name_pos_back === true) {
$string .= 'Month ';
}
if ($name_pos_back === false) {
$string .= 'Day ';
}
$string .= '<select id="day' . $suffix . '" name="day' . $suffix . '" onChange="' . $on_change_call . '">';
for ($i = 1; $i <= $days_in_month; $i++) {
// set weekday text based on current month ($month) and year ($year)
$string .= '<option value="' . ($i < 10 ? '0' . $i : $i) . '" '
. ($day == $i ? 'selected' : '') . '>' . $i
. ' (' . date('D', mktime(0, 0, 0, (int)$month, $i, (int)$year) ?: null) . ')</option>';
}
$string .= '</select> ';
if ($name_pos_back === true) {
$string .= 'Day ';
}
if ($name_pos_back === false) {
$string .= 'Hour ';
}
$string .= '<select id="hour' . $suffix . '" name="hour' . $suffix . '" onChange="' . $on_change_call . '">';
for ($i = 0; $i <= 23; $i += $min_steps) {
$string .= '<option value="' . ($i < 10 ? '0' . $i : $i)
. '" ' . ($hour == $i ? 'selected' : '') . '>' . $i . '</option>';
}
$string .= '</select> ';
if ($name_pos_back === true) {
$string .= 'Hour ';
}
if ($name_pos_back === false) {
$string .= 'Minute ';
}
$string .= '<select id="min' . $suffix . '" name="min'
. $suffix . '" onChange="' . $on_change_call . '">';
for ($i = 0; $i <= 59; $i++) {
$string .= '<option value="' . ($i < 10 ? '0' . $i : $i)
. '" ' . ($min == $i ? 'selected' : '') . '>' . $i . '</option>';
}
$string .= '</select>';
if ($name_pos_back === true) {
$string .= ' Minute ';
}
// return the datetime select string
return $string;
}
/**
* tries to find mailto:user@bubu.at and changes it into ->
* <a href="mailto:user@bubu.at">E-Mail senden</a>
* or tries to take any url (http, ftp, etc) and transform it into a valid URL
* the string is in the format: some url|name#css|, same for email
*
* @param string $string data to transform to a valid HTML url
* @param string $target target string, default _blank
* @return string correctly formed html url link
*/
public static function magicLinks(string $string, string $target = "_blank"): string
{
$output = $string;
$protList = ["http", "https", "ftp", "news", "nntp"];
// find urls w/o protocol
$output = preg_replace("/([^\/])www\.([\w\.-]+)\.([a-zA-Z]{2,4})/", "\\1http://www.\\2.\\3", $output) ?: '';
$output = preg_replace("/([^\/])ftp\.([\w\.-]+)\.([a-zA-Z]{2,4})/", "\\1ftp://ftp.\\2.\\3", $output) ?: '';
// remove doubles, generate protocol-regex
// DIRTY HACK
$protRegex = "";
foreach ($protList as $protocol) {
if ($protRegex) {
$protRegex .= "|";
}
$protRegex .= "$protocol:\/\/";
}
// find urls w/ protocol
// cs: escaped -, added / for http urls
// added | |, this time mandatory, todo: if no | |use \\1\\2
// backslash at the end of a url also allowed now
// do not touch <.*=".."> things!
// _1: URL or email
// _2: atag (>)
// _3: (_1) part of url or email [main url or email pre @ part]
// _4: (_2) parameters of url or email post @ part
// _5: (_3) parameters of url or tld part of email
// _7: link name/email link name
// _9: style sheet class
$output = preg_replace_callback(
"/(href=\")?(\>)?\b($protRegex)([\w\.\-?&=+%#~,;\/]+)\b([\.\-?&=+%#~,;\/]*)(\|([^\||^#]+)(#([^\|]+))?\|)?/",
function ($matches) {
return self::createUrl(
$matches[1] ?? '',
$matches[2] ?? '',
$matches[3] ?? '',
$matches[4] ?? '',
$matches[5] ?? '',
$matches[7] ?? '',
$matches[9] ?? ''
);
},
$output
) ?: '';
// find email-addresses, but not mailto prefix ones
$output = preg_replace_callback(
"/(mailto:)?(\>)?\b([\w\.-]+)@([\w\.\-]+)\.([a-zA-Z]{2,4})\b(\|([^\||^#]+)(#([^\|]+))?\|)?/",
function ($matches) {
return self::createEmail(
$matches[1] ?? '',
$matches[2] ?? '',
$matches[3] ?? '',
$matches[4] ?? '',
$matches[5] ?? '',
$matches[7] ?? '',
$matches[9] ?? ''
);
},
$output
) ?: '';
// we have one slashes after the Protocol ->
// internal link no domain, strip out the proto
// $output = preg_replace("/($protRegex)\/(.*)/e", "\\2", $ouput);
// post processing
$output = str_replace("{TARGET}", $target, $output);
$output = str_replace("##LT##", "<", $output);
$output = str_replace("##GT##", ">", $output);
$output = str_replace("##QUOT##", "\"", $output);
return $output;
}
/**
* internal function, called by the magic url create functions.
* checks if title $_4 exists, if not, set url as title
*
* @param string $href url link
* @param string $atag anchor tag (define both type or url)
* @param string $_1 part of the URL, if atag is set, _1 is not used
* @param string $_2 part of the URL
* @param string $_3 part of the URL
* @param string $name name for the url, if not given _2 + _3 is used
* @param string $class style sheet
* @return string correct string for url href process
*/
private static function createUrl($href, $atag, $_1, $_2, $_3, $name, $class): string
{
// $this->debug('URL', "1: $_1 - 2: $_2 - $_3 - atag: $atag - name: $name - class: $class");
// if $_1 ends with //, then we strip $_1 complete & target is also blanked (its an internal link)
if (preg_match("/\/\/$/", $_1) && preg_match("/^\//", $_2)) {
$_1 = '';
$target = '';
} else {
$target = '{TARGET}';
}
// if it is a link already just return the original link do not touch anything
if (!$href && !$atag) {
return "##LT##a href=##QUOT##" . $_1 . $_2 . $_3 . "##QUOT##"
. ($class ? ' class=##QUOT##' . $class . '##QUOT##' : '')
. ($target ? " target=##QUOT##" . $target . "##QUOT##" : '')
. "##GT##" . ($name ? $name : $_2 . $_3) . "##LT##/a##GT##";
} elseif ($href && !$atag) {
return "href=##QUOT##$_1$_2$_3##QUOT##";
} elseif ($atag) {
return $atag . $_2 . $_3;
} else {
return $href;
}
}
/**
* internal function for createing email, returns data to magic_url method
*
* @param string $mailto email address
* @param string $atag atag (define type of url)
* @param string $_1 parts of the email _1 before @, 3_ tld
* @param string $_2 _2 domain part after @
* @param string $_3 _3 tld
* @param string $title name for the link, if not given use email
* @param string $class style sheet
* @return string created html email a href string
*/
private static function createEmail($mailto, $atag, $_1, $_2, $_3, $title, $class)
{
$email = $_1 . "@" . $_2 . "." . $_3;
if (!$mailto && !$atag) {
return "##LT##a href=##QUOT##mailto:" . $email . "##QUOT##"
. ($class ? ' class=##QUOT##' . $class . '##QUOT##' : '')
. "##GT##" . ($title ? $title : $email) . "##LT##/a##GT##";
} elseif ($mailto && !$atag) {
return "mailto:" . $email;
} elseif ($atag) {
return $atag . $email;
} else {
// else just return email as is
return $email;
}
}
}
// __END__

2748
src/Output/Form/Generate.php Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,140 @@
<?php
declare(strict_types=1);
namespace CoreLibs\Output\Form\TableArrays;
class EditAccess implements \CoreLibs\Output\Form\TableArraysInterface
{
/** @var \CoreLibs\Output\Form\Generate */
private $form;
/**
* constructor
* @param \CoreLibs\Output\Form\Generate $form base form class
*/
public function __construct(\CoreLibs\Output\Form\Generate $form)
{
$this->form = $form;
$this->form->log->debug('CLASS LOAD', __NAMESPACE__ . __CLASS__);
}
/**
* return the table array
*
* @return array<mixed>
*/
public function setTableArray(): array
{
return [
'table_array' => [
'edit_access_id' => [
'value' => $_POST['edit_access_id'] ?? '',
'type' => 'hidden',
'pk' => 1
],
'name' => [
'value' => $_POST['name'] ?? '',
'output_name' => 'Access Group Name',
'mandatory' => 1,
'type' => 'text',
'error_check' => 'alphanumericspace|unique'
],
'description' => [
'value' => $_POST['description'] ?? '',
'output_name' => 'Description',
'type' => 'textarea'
],
'color' => [
'value' => $_POST['color'] ?? '',
'output_name' => 'Color',
'mandatory' => 0,
'type' => 'text',
'size' => 10,
'length' => 9,
'error_check' => 'custom',
// FIXME: update regex check for hex/rgb/hsl with color check class
'error_regex' => '/^#([\dA-Fa-f]{6}|[\dA-Fa-f]{8})$/',
'error_example' => '#F6A544'
],
'enabled' => [
'value' => $_POST['enabled'] ?? 0,
'output_name' => 'Enabled',
'type' => 'binary',
'int' => 1, // OR 'bool' => 1
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
],
'protected' => [
'value' => $_POST['protected'] ?? 0,
'output_name' => 'Protected',
'type' => 'binary',
'int' => 1,
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
],
'additional_acl' => [
'value' => $_POST['additional_acl'] ?? '',
'output_name' => 'Additional ACL (as JSON)',
'type' => 'textarea',
'error_check' => 'json',
'rows' => 10,
'cols' => 60
],
],
'table_name' => 'edit_access',
"load_query" => "SELECT edit_access_id, name FROM edit_access ORDER BY name",
'show_fields' => [
[
'name' => 'name'
],
],
'element_list' => [
'edit_access_data' => [
'output_name' => 'Edit Access Data',
'delete_name' => 'remove_edit_access_data',
// is not a sub table read and connect, but only a sub table with data
// 'type' => 'reference_data',
// maxium visible if no data is set, if filled add this number to visible
'max_empty' => 5,
'prefix' => 'ead',
'elements' => [
'name' => [
'type' => 'text',
'error_check' => 'alphanumeric|unique',
'output_name' => 'Name',
'mandatory' => 1
],
'value' => [
'type' => 'text',
'output_name' => 'Value'
],
'enabled' => [
'type' => 'checkbox',
'output_name' => 'Activate',
'int' => 1,
'element_list' => [1]
],
/*'edit_access_id' => [
'int' => 1,
'type' => 'hidden',
// reference main key from master table above
'fk_id' => 1
],*/
'edit_access_data_id' => [
'type' => 'hidden',
'int' => 1,
'pk_id' => 1
],
],
],
],
];
}
}
// __END__

View File

@@ -0,0 +1,137 @@
<?php
declare(strict_types=1);
namespace CoreLibs\Output\Form\TableArrays;
class EditGroups implements \CoreLibs\Output\Form\TableArraysInterface
{
/** @var \CoreLibs\Output\Form\Generate */
private $form;
/**
* constructor
* @param \CoreLibs\Output\Form\Generate $form base form class
*/
public function __construct(\CoreLibs\Output\Form\Generate $form)
{
$this->form = $form;
$this->form->log->debug('CLASS LOAD', __NAMESPACE__ . __CLASS__);
}
/**
* return the table array
*
* @return array<mixed>
*/
public function setTableArray(): array
{
return [
'table_array' => [
'edit_group_id' => [
'value' => $_POST['edit_group_id'] ?? '',
'pk' => 1,
'type' => 'hidden'
],
'enabled' => [
'value' => $_POST['enabled'] ?? '',
'output_name' => 'Enabled',
'int' => 1,
'type' => 'binary',
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
],
'name' => [
'value' => $_POST['name'] ?? '',
'output_name' => 'Group Name',
'type' => 'text',
'mandatory' => 1
],
'edit_access_right_id' => [
'value' => $_POST['edit_access_right_id'] ?? '',
'output_name' => 'Group Level',
'mandatory' => 1,
'int' => 1,
'type' => 'drop_down_db',
'query' => "SELECT edit_access_right_id, name FROM edit_access_right ORDER BY level"
],
'edit_scheme_id' => [
'value' => $_POST['edit_scheme_id'] ?? '',
'output_name' => 'Group Scheme',
'int_null' => 1,
'type' => 'drop_down_db',
'query' => "SELECT edit_scheme_id, name FROM edit_scheme WHERE enabled = 1 ORDER BY name"
],
'additional_acl' => [
'value' => $_POST['additional_acl'] ?? '',
'output_name' => 'Additional ACL (as JSON)',
'type' => 'textarea',
'error_check' => 'json',
'rows' => 10,
'cols' => 60
],
],
'load_query' => "SELECT edit_group_id, name, enabled FROM edit_group ORDER BY name",
'table_name' => 'edit_group',
'show_fields' => [
[
'name' => 'name'
],
[
'name' => 'enabled',
'binary' => ['Yes', 'No'],
'before_value' => 'Enabled: '
],
],
'element_list' => [
'edit_page_access' => [
'output_name' => 'Pages',
'mandatory' => 1,
'delete' => 0, // set then reference entries are deleted, else the 'enable' flag is only set
'enable_name' => 'enable_page_access',
'prefix' => 'epa',
'read_data' => [
'table_name' => 'edit_page',
'pk_id' => 'edit_page_id',
'name' => 'name',
'order' => 'order_number'
],
'elements' => [
'edit_page_access_id' => [
'type' => 'hidden',
'int' => 1,
'pk_id' => 1
],
'enabled' => [
'type' => 'checkbox',
'output_name' => 'Activate',
'int' => 1,
'element_list' => [1],
],
'edit_access_right_id' => [
'type' => 'drop_down_db',
'output_name' => 'Access Level',
'int' => 1,
'preset' => 1, // first of the select
'query' => "SELECT edit_access_right_id, name FROM edit_access_right ORDER BY level"
],
'edit_page_id' => [
'int' => 1,
'type' => 'hidden'
],
/*,
'edit_default' => [
'output_name' => 'Default',
'type' => 'radio',
'mandatory' => 1
],*/
],
], // edit pages ggroup
],
];
}
}
// __END__

View File

@@ -0,0 +1,105 @@
<?php
declare(strict_types=1);
namespace CoreLibs\Output\Form\TableArrays;
class EditLanguages implements \CoreLibs\Output\Form\TableArraysInterface
{
/** @var \CoreLibs\Output\Form\Generate */
private $form;
/**
* constructor
* @param \CoreLibs\Output\Form\Generate $form base form class
*/
public function __construct(\CoreLibs\Output\Form\Generate $form)
{
$this->form = $form;
$this->form->log->debug('CLASS LOAD', __NAMESPACE__ . __CLASS__);
}
/**
* return the table array
*
* @return array<mixed>
*/
public function setTableArray(): array
{
return [
'table_array' => [
'edit_language_id' => [
'value' => $_POST['edit_language_id'] ?? '',
'type' => 'hidden',
'pk' => 1
],
'short_name' => [
'value' => $_POST['short_name'] ?? '',
'output_name' => 'Language (short)',
'mandatory' => 1,
'type' => 'text',
'size' => 2,
'length' => 2
],
'long_name' => [
'value' => $_POST['long_name'] ?? '',
'output_name' => 'Language (long)',
'mandatory' => 1,
'type' => 'text',
'size' => 40
],
'iso_name' => [
'value' => $_POST['iso_name'] ?? '',
'output_name' => 'ISO Code',
'mandatory' => 1,
'type' => 'text'
],
'order_number' => [
'value' => $_POST['order_number'] ?? '',
'int' => 1,
'order' => 1
],
'enabled' => [
'value' => $_POST['enabled'] ?? '',
'output_name' => 'Enabled',
'int' => 1,
'type' => 'binary',
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
],
'lang_default' => [
'value' => $_POST['lang_default'] ?? '',
'output_name' => 'Default Language',
'int' => 1,
'type' => 'binary',
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
],
],
'load_query' => "SELECT edit_language_id, long_name, iso_name, enabled "
. "FROM edit_language "
. "ORDER BY long_name",
'show_fields' => [
[
'name' => 'long_name'
],
[
'name' => 'iso_name',
'before_value' => 'ISO: '
],
[
'name' => 'enabled',
'before_value' => 'Enabled: ',
'binary' => ['Yes','No'],
],
],
'table_name' => 'edit_language'
];
}
}
// __END__

View File

@@ -0,0 +1,68 @@
<?php
declare(strict_types=1);
namespace CoreLibs\Output\Form\TableArrays;
class EditMenuGroup implements \CoreLibs\Output\Form\TableArraysInterface
{
/** @var \CoreLibs\Output\Form\Generate */
private $form;
/**
* constructor
* @param \CoreLibs\Output\Form\Generate $form base form class
*/
public function __construct(\CoreLibs\Output\Form\Generate $form)
{
$this->form = $form;
$this->form->log->debug('CLASS LOAD', __NAMESPACE__ . __CLASS__);
}
/**
* return the table array
*
* @return array<mixed>
*/
public function setTableArray(): array
{
return [
'table_array' => [
'edit_menu_group_id' => [
'value' => $_POST['edit_menu_group_id'] ?? '',
'type' => 'hidden',
'pk' => 1
],
'name' => [
'value' => $_POST['name'] ?? '',
'output_name' => 'Group name',
'mandatory' => 1,
'type' => 'text'
],
'flag' => [
'value' => $_POST['flag'] ?? '',
'output_name' => 'Flag',
'mandatory' => 1,
'type' => 'text',
'error_check' => 'alphanumeric|unique'
],
'order_number' => [
'value' => $_POST['order_number'] ?? '',
'output_name' => 'Group order',
'type' => 'order',
'int' => 1,
'order' => 1
],
],
'table_name' => 'edit_menu_group',
'load_query' => "SELECT edit_menu_group_id, name FROM edit_menu_group ORDER BY name",
'show_fields' => [
[
'name' => 'name'
],
],
];
}
}
// __END__

View File

@@ -0,0 +1,275 @@
<?php
declare(strict_types=1);
namespace CoreLibs\Output\Form\TableArrays;
class EditPages implements \CoreLibs\Output\Form\TableArraysInterface
{
/** @var \CoreLibs\Output\Form\Generate */
private $form;
/**
* constructor
* @param \CoreLibs\Output\Form\Generate $form base form class
*/
public function __construct(\CoreLibs\Output\Form\Generate $form)
{
$this->form = $form;
$this->form->log->debug('CLASS LOAD', __NAMESPACE__ . __CLASS__);
}
/**
* return the table array
*
* @return array<mixed>
*/
public function setTableArray(): array
{
return [
'table_array' => [
'edit_page_id' => [
'value' => $_POST['edit_page_id'] ?? '',
'type' => 'hidden',
'pk' => 1
],
'filename' => [
'value' => $_POST['filename'] ?? '',
'output_name' => 'Add File ...',
'mandatory' => 1,
'type' => 'drop_down_db',
'query' => "SELECT DISTINCT temp_files.filename AS id, "
. "temp_files.folder || temp_files.filename AS name "
. "FROM temp_files "
. "LEFT JOIN edit_page ep ON temp_files.filename = ep.filename "
. "WHERE ep.filename IS NULL"
],
'hostname' => [
'value' => $_POST['hostname'] ?? '',
'output_name' => 'Hostname or folder',
'type' => 'text'
],
'name' => [
'value' => $_POST['name'] ?? '',
'output_name' => 'Page name',
'mandatory' => 1,
'type' => 'text'
],
'order_number' => [
'value' => $_POST['order_number'] ?? '',
'output_name' => 'Page order',
'type' => 'order',
'int' => 1,
'order' => 1
],
/* 'flag' => [
'value' => $_POST['flag']) ?? '',
'output_name' => 'Page Flag',
'type' => 'drop_down_array',
'query' => [
'0' => '0',
'1' => '1',
'2' => '2',
'3' => '3',
'4' => '4',
'5' => '5'
],
],*/
'online' => [
'value' => $_POST['online'] ?? '',
'output_name' => 'Online',
'int' => 1,
'type' => 'binary',
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
],
'menu' => [
'value' => $_POST['menu'] ?? '',
'output_name' => 'Menu',
'int' => 1,
'type' => 'binary',
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
],
'popup' => [
'value' => $_POST['popup'] ?? '',
'output_name' => 'Popup',
'int' => 1,
'type' => 'binary',
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
],
'popup_x' => [
'value' => $_POST['popup_x'] ?? '',
'output_name' => 'Popup Width',
'int_null' => 1,
'type' => 'text',
'size' => 4,
'length' => 4
],
'popup_y' => [
'value' => $_POST['popup_y'] ?? '',
'output_name' => 'Popup Height',
'int_null' => 1,
'type' => 'text',
'size' => 4,
'length' => 4
],
'content_alias_edit_page_id' => [
'value' => $_POST['content_alias_edit_page_id'] ?? '',
'output_name' => 'Content Alias Source',
'int_null' => 1,
'type' => 'drop_down_db',
// query creation
'select_distinct' => 0,
'pk_name' => 'edit_page_id AS content_alias_edit_page_id',
'input_name' => 'name',
'table_name' => 'edit_page',
'where_not_self' => 1,
'order_by' => 'order_number'
// 'query' => "SELECT edit_page_id AS content_alias_edit_page_id, name ".
// "FROM edit_page ".
// (!empty($_POST['edit_page_id']) ? " WHERE edit_page_id <> ".$_POST['edit_page_id'] : "")." ".
// "ORDER BY order_number"
],
],
'load_query' => "SELECT edit_page_id, "
. "CASE WHEN hostname IS NOT NULL THEN hostname ELSE ''::VARCHAR END || filename AS filename, "
. "name, online, menu, popup "
. "FROM edit_page "
. "ORDER BY order_number",
'table_name' => 'edit_page',
'show_fields' => [
[
'name' => 'name'
],
[
'name' => 'filename',
'before_value' => 'Filename: '
],
[
'name' => 'online',
'binary' => ['Yes', 'No'],
'before_value' => 'Online: '
],
[
'name' => 'menu',
'binary' => ['Yes', 'No'],
'before_value' => 'Menu: '
],
[
'name' => 'popup',
'binary' => ['Yes', 'No'],
'before_value' => 'Popup: '
],
],
'reference_arrays' => [
'edit_visible_group' => [
'table_name' => 'edit_page_visible_group',
'other_table_pk' => 'edit_visible_group_id',
'output_name' => 'Visible Groups (access)',
'mandatory' => 1,
'select_size' => 10,
'selected' => $_POST['edit_visible_group_id'] ?? '',
'query' => "SELECT edit_visible_group_id, 'Name: ' || name || ', ' || 'Flag: ' || flag "
. "FROM edit_visible_group ORDER BY name"
],
'edit_menu_group' => [
'table_name' => 'edit_page_menu_group',
'other_table_pk' => 'edit_menu_group_id',
'output_name' => 'Menu Groups (grouping)',
'mandatory' => 1,
'select_size' => 10,
'selected' => $_POST['edit_menu_group_id'] ?? '',
'query' => "SELECT edit_menu_group_id, 'Name: ' || name || ', ' || 'Flag: ' || flag "
. "FROM edit_menu_group ORDER BY order_number"
],
],
'element_list' => [
'edit_query_string' => [
'output_name' => 'Query Strings',
'delete_name' => 'remove_query_string',
'prefix' => 'eqs',
'elements' => [
'name' => [
'output_name' => 'Name',
'type' => 'text',
'error_check' => 'unique|alphanumeric',
'mandatory' => 1
],
'value' => [
'output_name' => 'Value',
'type' => 'text'
],
'enabled' => [
'output_name' => 'Enabled',
'int' => 1,
'type' => 'checkbox',
'element_list' => [1],
],
'dynamic' => [
'output_name' => 'Dynamic',
'int' => 1,
'type' => 'checkbox',
'element_list' => [1],
],
'edit_query_string_id' => [
'type' => 'hidden',
'pk_id' => 1
],
], // elements
], // query_string element list
'edit_page_content' => [
'output_name' => 'Page Content',
'delete_name' => 'remove_page_content',
'prefix' => 'epc',
'elements' => [
'name' => [
'output_name' => 'Content',
'type' => 'text',
'error_check' => 'alphanumeric',
'mandatory' => 1
],
'uid' => [
'output_name' => 'UID',
'type' => 'text',
'error_check' => 'unique|alphanumeric',
'mandatory' => 1
],
'order_number' => [
'output_name' => 'Order',
'type' => 'text',
'error_check' => 'int',
'mandatory' => 1
],
'online' => [
'output_name' => 'Online',
'int' => 1,
'type' => 'checkbox',
'element_list' => [1],
],
'edit_access_right_id' => [
'type' => 'drop_down_db',
'output_name' => 'Access Level',
'int' => 1,
'preset' => 1, // first of the select
'query' => "SELECT edit_access_right_id, name FROM edit_access_right ORDER BY level"
],
'edit_page_content_id' => [
'type' => 'hidden',
'pk_id' => 1
],
],
],
], // element list
];
}
}
// __END__

View File

@@ -0,0 +1,86 @@
<?php
declare(strict_types=1);
namespace CoreLibs\Output\Form\TableArrays;
class EditSchemas implements \CoreLibs\Output\Form\TableArraysInterface
{
/** @var \CoreLibs\Output\Form\Generate */
private $form;
/**
* constructor
* @param \CoreLibs\Output\Form\Generate $form base form class
*/
public function __construct(\CoreLibs\Output\Form\Generate $form)
{
$this->form = $form;
$this->form->log->debug('CLASS LOAD', __NAMESPACE__ . __CLASS__);
}
/**
* return the table array
*
* @return array<mixed>
*/
public function setTableArray(): array
{
return [
'table_array' => [
'edit_scheme_id' => [
'value' => $_POST['edit_scheme_id'] ?? '',
'type' => 'hidden',
'pk' => 1
],
'name' => [
'value' => $_POST['name'] ?? '',
'output_name' => 'Scheme Name',
'mandatory' => 1,
'type' => 'text'
],
'header_color' => [
'value' => $_POST['header_color'] ?? '',
'output_name' => 'Header Color',
'mandatory' => 1,
'type' => 'text',
'size' => 10,
'length' => 9,
'error_check' => 'custom',
// FIXME: update regex check for hex/rgb/hsl with color check class
'error_regex' => '/^#([\dA-Fa-f]{6}|[\dA-Fa-f]{8})$/',
'error_example' => '#F6A544'
],
'enabled' => [
'value' => $_POST['enabled'] ?? '',
'output_name' => 'Enabled',
'int' => 1,
'type' => 'binary',
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
],
'template' => [
'value' => $_POST['template'] ?? '',
'output_name' => 'Template',
'type' => 'text'
],
],
'table_name' => 'edit_scheme',
'load_query' => "SELECT edit_scheme_id, name, enabled FROM edit_scheme ORDER BY name",
'show_fields' => [
[
'name' => 'name'
],
[
'name' => 'enabled',
'binary' => ['Yes', 'No'],
'before_value' => 'Enabled: '
],
],
];
}
}
// __END__

View File

@@ -0,0 +1,456 @@
<?php
declare(strict_types=1);
namespace CoreLibs\Output\Form\TableArrays;
class EditUsers implements \CoreLibs\Output\Form\TableArraysInterface
{
/** @var \CoreLibs\Output\Form\Generate */
private $form;
/**
* constructor
* @param \CoreLibs\Output\Form\Generate $form base form class
*/
public function __construct(\CoreLibs\Output\Form\Generate $form)
{
$this->form = $form;
$this->form->log->debug('CLASS LOAD', __NAMESPACE__ . __CLASS__);
}
/**
* return the table array
*
* @return array<mixed>
*/
public function setTableArray(): array
{
return [
'table_array' => [
'edit_user_id' => [
'value' => $_POST['edit_user_id'] ?? '',
'type' => 'hidden',
'pk' => 1,
'int' => 1
],
'username' => [
'value' => $_POST['username'] ?? '',
'output_name' => 'Username',
'mandatory' => 1,
'error_check' => 'unique|alphanumericextended',
'type' => 'text',
// if not min_edit_acl only read
// if not min_show_acl not visible
'min_edit_acl' => '100',
'min_show_acl' => '-1',
],
'password' => [
'value' => $_POST['password'] ?? '',
'HIDDEN_value' => $_POST['HIDDEN_password'] ?? '',
'CONFIRM_value' => $_POST['CONFIRM_password'] ?? '',
'output_name' => 'Password',
'mandatory' => 1,
'type' => 'password', // later has to be password for encryption in database
'update' => [ // connected field updates, and update data
'password_change_date' => [ // db row to update
'type' => 'date', // type of field (int/text/date/etc)
'value' => 'NOW()' // value [todo: complex reference
],
],
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
// password date when first insert and password is set, needs special field with connection to password
// password reset force interval, if set, user needs to reset password after X time period
'password_change_interval' => [
'value' => $_POST['password_change_interval'] ?? '',
'output_name' => 'Password change interval',
// can be any date length format. n Y/M/D [not H/M/S], only one set, no combination
'error_check' => 'intervalshort',
'type' => 'text',
'interval' => 1, // interval needs NULL write for empty
'size' => 5, // make it 5 chars long
'length' => 5,
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'enabled' => [
'value' => $_POST['enabled'] ?? '',
'output_name' => 'Enabled',
'type' => 'binary',
'int' => 1,
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
'min_edit_acl' => '100',
'min_show_acl' => '-1',
],
'deleted' => [
'value' => $_POST['deleted'] ?? '',
'output_name' => 'Deleted',
'type' => 'binary',
'int' => 1,
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'strict' => [
'value' => $_POST['strict'] ?? '',
'output_name' => 'Strict (Lock after errors)',
'type' => 'binary',
'int' => 1,
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'locked' => [
'value' => $_POST['locked'] ?? '',
'output_name' => 'Locked (auto set if strict with errors)',
'type' => 'binary',
'int' => 1,
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'admin' => [
'value' => $_POST['admin'] ?? '',
'output_name' => 'Admin',
'type' => 'binary',
'int' => 1,
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'debug' => [
'value' => $_POST['debug'] ?? '',
'output_name' => 'Debug',
'type' => 'binary',
'int' => 1,
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'db_debug' => [
'value' => $_POST['db_debug'] ?? '',
'output_name' => 'DB Debug',
'type' => 'binary',
'int' => 1,
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'email' => [
'value' => $_POST['email'] ?? '',
'output_name' => 'E-Mail',
'type' => 'text',
'error_check' => 'email',
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'last_name' => [
'value' => $_POST['last_name'] ?? '',
'output_name' => 'Last Name',
'type' => 'text',
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'first_name' => [
'value' => $_POST['first_name'] ?? '',
'output_name' => 'First Name',
'type' => 'text',
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'lock_until' => [
'value' => $_POST['lock_until'] ?? '',
'output_name' => 'Lock account until',
'type' => 'datetime',
'error_check' => 'datetime',
'sql_read' => 'YYYY-MM-DD HH24:MI',
'datetime' => 1,
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'lock_after' => [
'value' => $_POST['lock_after'] ?? '',
'output_name' => 'Lock account after',
'type' => 'datetime',
'error_check' => 'datetime',
'sql_read' => 'YYYY-MM-DD HH24:MI',
'datetime' => 1,'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'login_user_id' => [
'value' => $_POST['login_user_id'] ?? '',
'output_name' => '_GET/_POST loginUserId direct login ID',
'type' => 'text',
'error_check' => 'unique|custom',
'error_regex' => "/^[A-Za-z0-9]+$/",
'emptynull' => 1,'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'login_user_id_set_date' => [
'output_name' => 'loginUserId set date',
'value' => $_POST['login_user_id_set_date'] ?? '',
'type' => 'view',
'empty' => '-',
'min_show_acl' => '100',
],
'login_user_id_last_revalidate' => [
'output_name' => 'loginUserId last revalidate date',
'value' => $_POST['login_user_id_last_revalidate'] ?? '',
'type' => 'view',
'empty' => '-',
'min_show_acl' => '100',
],
'login_user_id_locked' => [
'value' => $_POST['login_user_id_locked'] ?? '',
'output_name' => 'loginUserId usage locked',
'type' => 'binary',
'int' => 1,
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'login_user_id_revalidate_after' => [
'value' => $_POST['login_user_id_revalidate_after'] ?? '',
'output_name' => 'loginUserId, User must login after n days',
'type' => 'text',
'error_check' => 'intervalshort',
'interval' => 1, // interval needs NULL write for empty
'size' => 5, // make it 5 chars long
'length' => 5,
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'login_user_id_valid_from' => [
'value' => $_POST['login_user_id_valid_from'] ?? '',
'output_name' => 'loginUserId valid from',
'type' => 'datetime',
'error_check' => 'datetime',
'sql_read' => 'YYYY-MM-DD HH24:MI',
'datetime' => 1,
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'login_user_id_valid_until' => [
'value' => $_POST['login_user_id_valid_until'] ?? '',
'output_name' => 'loginUserId valid until',
'type' => 'datetime',
'error_check' => 'datetime',
'sql_read' => 'YYYY-MM-DD HH24:MI',
'datetime' => 1,
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'edit_language_id' => [
'value' => $_POST['edit_language_id'] ?? '',
'output_name' => 'Language',
'mandatory' => 1,
'int' => 1,
'type' => 'drop_down_db',
'query' => "SELECT edit_language_id, long_name "
. "FROM edit_language "
. "WHERE enabled = 1"
. "ORDER BY order_number",
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'edit_scheme_id' => [
'value' => $_POST['edit_scheme_id'] ?? '',
'output_name' => 'Scheme',
'int_null' => 1,
'type' => 'drop_down_db',
'query' => "SELECT edit_scheme_id, name FROM edit_scheme WHERE enabled = 1 ORDER BY name",
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'edit_group_id' => [
'value' => $_POST['edit_group_id'] ?? '',
'output_name' => 'Group',
'int' => 1,
'type' => 'drop_down_db',
'query' => "SELECT edit_group_id, name FROM edit_group WHERE enabled = 1 ORDER BY name",
'mandatory' => 1,
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'edit_access_right_id' => [
'value' => $_POST['edit_access_right_id'] ?? '',
'output_name' => 'User Level',
'mandatory' => 1,
'int' => 1,
'type' => 'drop_down_db',
'query' => "SELECT edit_access_right_id, name FROM edit_access_right ORDER BY level",
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'login_error_count' => [
'output_name' => 'Login error count',
'value' => $_POST['login_error_count'] ?? '',
'type' => 'view',
'empty' => '0',
'min_show_acl' => '100',
],
'login_error_date_last' => [
'output_name' => 'Last login error',
'value' => $_POST['login_error_date_liast'] ?? '',
'type' => 'view',
'empty' => '-',
'min_show_acl' => '100',
],
'login_error_date_first' => [
'output_name' => 'First login error',
'value' => $_POST['login_error_date_first'] ?? '',
'type' => 'view',
'empty' => '-',
'min_show_acl' => '100',
],
'protected' => [
'value' => $_POST['protected'] ?? '',
'output_name' => 'Protected',
'type' => 'binary',
'int' => 1,
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'additional_acl' => [
'value' => $_POST['additional_acl'] ?? '',
'output_name' => 'Additional ACL (as JSON)',
'type' => 'textarea',
'error_check' => 'json',
'rows' => 10,
'cols' => 60,
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
],
'load_query' => "SELECT edit_user_id, username, enabled, deleted, "
. "strict, locked, login_error_count "
. "FROM edit_user "
// if base acl is not 90 only list enabled
// if not admin flag, do not list admin flagged
. (
!$this->form->getAclAdmin() ?
"WHERE admin = 0 "
. (
!$this->form->checkBaseACL(90) ?
// $_POST['base_acl_level'] < 90 ?
"AND enabled = 1 " :
""
)
: ''
)
. "ORDER BY username",
'table_name' => 'edit_user',
'show_fields' => [
[
'name' => 'username'
],
[
'name' => 'enabled',
'binary' => ['Yes', 'No'],
'before_value' => 'ENBL: '
],
[
'name' => 'deleted',
'binary' => ['Yes', 'No'],
'before_value' => 'DEL: '
],
[
'name' => 'strict',
'binary' => ['Yes', 'No'],
'before_value' => 'STRC: '
],
[
'name' => 'locked',
'binary' => ['Yes', 'No'],
'before_value' => 'LCK: '
],
[
'name' => 'login_error_count',
'before_value' => 'ERR: '
],
],
'element_list' => [
'edit_access_user' => [
'output_name' => 'Accounts',
'mandatory' => 1,
// set then reference entries are deleted, else the 'enable' flag is only set
'delete' => 0,
// acl
'min_edit_acl' => '40',
'min_show_acl' => '20',
// table read prefix
'prefix' => 'ecu',
'read_data' => [
'table_name' => 'edit_access',
'pk_id' => 'edit_access_id',
'name' => 'name',
'order' => 'name'
],
'elements' => [
'edit_access_user_id' => [
'output_name' => 'Activate',
'type' => 'hidden',
'int' => 1,
'pk_id' => 1
],
'enabled' => [
'type' => 'checkbox',
'output_name' => 'Activate',
'int' => 1,
'element_list' => [1],
],
'edit_access_right_id' => [
'type' => 'drop_down_db',
'output_name' => 'Access Level',
'preset' => 1, // first of the select
'int' => 1,
'query' => "SELECT edit_access_right_id, name FROM edit_access_right ORDER BY level"
],
'edit_default' => [
'type' => 'radio_group',
'output_name' => 'Default',
'int' => 1,
'element_list' => 'radio_group'
],
'edit_access_id' => [
'type' => 'hidden',
'int' => 1
],
],
], // edit pages ggroup
],
];
}
}
// __END__

View File

@@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
namespace CoreLibs\Output\Form\TableArrays;
class EditVisibleGroup implements \CoreLibs\Output\Form\TableArraysInterface
{
/** @var \CoreLibs\Output\Form\Generate */
private $form;
/**
* constructor
* @param \CoreLibs\Output\Form\Generate $form base form class
*/
public function __construct(\CoreLibs\Output\Form\Generate $form)
{
$this->form = $form;
$this->form->log->debug('CLASS LOAD', __NAMESPACE__ . __CLASS__);
}
/**
* return the table array
*
* @return array<mixed>
*/
public function setTableArray(): array
{
return [
'table_array' => [
'edit_visible_group_id' => [
'value' => $_POST['edit_visible_group_id'] ?? '',
'type' => 'hidden',
'pk' => 1
],
'name' => [
'value' => $_POST['name'] ?? '',
'output_name' => 'Group name',
'mandatory' => 1,
'type' => 'text'
],
'flag' => [
'value' => $_POST['flag'] ?? '',
'output_name' => 'Flag',
'mandatory' => 1,
'type' => 'text',
'error_check' => 'alphanumeric|unique'
],
],
'table_name' => 'edit_visible_group',
'load_query' => "SELECT edit_visible_group_id, name FROM edit_visible_group ORDER BY name",
'show_fields' => [
[
'name' => 'name'
],
],
];
}
}
// __END__

45
src/Output/Form/Token.php Normal file
View File

@@ -0,0 +1,45 @@
<?php
/*
* sets a form token in the _SESSION variable
* session must be started for this to work
*/
declare(strict_types=1);
namespace CoreLibs\Output\Form;
class Token
{
/**
* sets a form token in a session and returns form token
*
* @param string $name optional form name, default form_token
* @return string token name for given form id string
*/
public static function setFormToken(string $name = 'form_token'): string
{
// current hard set to sha256
$token = uniqid(hash('sha256', (string)rand()));
$_SESSION[$name] = $token;
return $token;
}
/**
* checks if the form token matches the session set form token
*
* @param string $token token string to check
* @param string $name optional form name to check to, default form_token
* @return bool false if not set, or true/false if matching or not mtaching
*/
public static function validateFormToken(string $token, string $name = 'form_token'): bool
{
if (isset($_SESSION[$name])) {
return $_SESSION[$name] === $token;
} else {
return false;
}
}
}
// __END_

493
src/Output/Image.php Normal file
View File

@@ -0,0 +1,493 @@
<?php
/*
* image thumbnail, rotate, etc
*/
declare(strict_types=1);
namespace CoreLibs\Output;
class Image
{
/**
* converts picture to a thumbnail with max x and max y size
*
* @param string $pic source image file with or without path
* @param int $size_x maximum size width
* @param int $size_y maximum size height
* @param string $dummy empty, or file_type to show an icon
* instead of nothing if file is not found
* @param string $path if source start is not ROOT path,
* if empty ROOT is choosen
* @param string $cache_source cache path, if not given TMP is used
* @param bool $clear_cache if set to true, will create thumb all the tame
* @return string|bool thumbnail name, or false for error
*/
public static function createThumbnail(
string $pic,
int $size_x,
int $size_y,
string $dummy = '',
string $path = '',
string $cache_source = '',
bool $clear_cache = false
) {
// get image type flags
$image_types = [
1 => 'gif',
2 => 'jpg',
3 => 'png'
];
$return_data = false;
$CONVERT = '';
// if CONVERT is not defined, abort
/** @phan-suppress-next-line PhanUndeclaredConstant */
if (defined('CONVERT') && is_executable(CONVERT)) {
/** @phan-suppress-next-line PhanUndeclaredConstant */
$CONVERT = CONVERT;
} else {
return $return_data;
}
if (!empty($cache_source)) {
$tmp_src = $cache_source;
} else {
$tmp_src = BASE . TMP;
}
// check if pic has a path, and override next sets
if (strstr($pic, '/') === false) {
if (empty($path)) {
$path = BASE;
}
$filename = $path . MEDIA . PICTURES . $pic;
} else {
$filename = $pic;
// and get the last part for pic (the filename)
$tmp = explode('/', $pic);
$pic = $tmp[(count($tmp) - 1)];
}
// does this picture exist and is it a picture
if (file_exists($filename) && is_file($filename)) {
[$width, $height, $type] = getimagesize($filename) ?: [];
$convert_prefix = '';
$create_file = false;
$delete_filename = '';
// check if we can skip the PDF creation: if we have size, if do not have type, we assume type png
if (!$type && is_numeric($size_x) && is_numeric($size_y)) {
$check_thumb = $tmp_src . 'thumb_' . $pic . '_' . $size_x . 'x' . $size_y . '.' . $image_types[3];
if (!is_file($check_thumb)) {
$create_file = true;
} else {
$type = 3;
}
}
// if type is not in the list, but returns as PDF, we need to convert to JPEG before
if (!$type) {
$output = [];
$return = null;
// is this a PDF, if no, return from here with nothing
$convert_prefix = 'png:';
# TEMP convert to PNG, we then override the file name
$convert_string = $CONVERT . ' ' . $filename . ' ' . $convert_prefix . $filename . '_TEMP';
$status = exec($convert_string, $output, $return);
$filename .= '_TEMP';
// for delete, in case we need to glob
$delete_filename = $filename;
// find file, if we can't find base name, use -0 as the first one (ignore other pages in multiple ones)
if (!is_file($filename)) {
$filename .= '-0';
}
[$width, $height, $type] = getimagesize($filename) ?: [];
}
// if no size given, set size to original
if (!$size_x || $size_x < 1 || !is_numeric($size_x)) {
$size_x = $width;
}
if (!$size_y || $size_y < 1 || !is_numeric($size_y)) {
$size_y = $height;
}
$thumb = 'thumb_' . $pic . '_' . $size_x . 'x' . $size_y . '.' . $image_types[$type];
$thumbnail = $tmp_src . $thumb;
// check if we already have this picture converted
if (!is_file($thumbnail) || $clear_cache == true) {
// convert the picture
if ($width > $size_x) {
$convert_string = $CONVERT . ' -geometry ' . $size_x . 'x ' . $filename . ' ' . $thumbnail;
$status = exec($convert_string, $output, $return);
// get the size of the converted data, if converted
if (is_file($thumbnail)) {
[$width, $height, $type] = getimagesize($thumbnail) ?: [];
}
}
if ($height > $size_y) {
$convert_string = $CONVERT . ' -geometry x' . $size_y . ' ' . $filename . ' ' . $thumbnail;
$status = exec($convert_string, $output, $return);
}
}
if (!is_file($thumbnail)) {
copy($filename, $thumbnail);
}
$return_data = $thumb;
// if we have a delete filename, delete here with glob
if ($delete_filename) {
array_map('unlink', glob($delete_filename . '*') ?: []);
}
} else {
if (!empty($dummy) && strstr($dummy, '/') === false) {
// check if we have the "dummy" image flag set
$filename = PICTURES . ICONS . strtoupper($dummy) . ".png";
/** @phpstan-ignore-next-line */
if (!empty($dummy) && file_exists($filename) && is_file($filename)) {
$return_data = $filename;
} else {
$return_data = false;
}
} else {
$filename = $dummy;
}
}
return $return_data;
}
/**
* simple thumbnail creation for jpeg, png only
* TODO: add other types like gif, etc
* - bails with false on failed create
* - if either size_x or size_y are empty (0)
* the resize is to max of one size
* if both are set, those are the max sizes (aspect ration is always ekpt)
* - if path is not given will cache folder for current path set
*
* @param string $filename source file name with full path
* @param int $thumb_width thumbnail width
* @param int $thumb_height thumbnail height
* @param string|null $thumbnail_path altnerative path for thumbnails
* @param bool $create_dummy if we encounter an invalid file
* create a dummy image file and return it
* @param bool $use_cache default to true, set to false to skip
* creating new image if exists
* @param bool $high_quality default to true, uses sample version,
* set to false to not use (default true)
* to use quick but less nice version
* @param int $jpeg_quality default 80, set image quality for jpeg only
* @return string|bool thumbnail with path
*/
public static function createThumbnailSimple(
string $filename,
int $thumb_width = 0,
int $thumb_height = 0,
?string $thumbnail_path = null,
bool $create_dummy = true,
bool $use_cache = true,
bool $high_quality = true,
int $jpeg_quality = 80
) {
$thumbnail = false;
// $this->debug('IMAGE PREPARE', "FILE: $filename (exists "
// .(string)file_exists($filename)."), WIDTH: $thumb_width, HEIGHT: $thumb_height");
// check that input image exists and is either jpeg or png
// also fail if the basic CACHE folder does not exist at all
if (
file_exists($filename) &&
is_dir(BASE . LAYOUT . CONTENT_PATH . CACHE) &&
is_writable(BASE . LAYOUT . CONTENT_PATH . CACHE)
) {
// $this->debug('IMAGE PREPARE', "FILENAME OK, THUMB WIDTH/HEIGHT OK");
[$inc_width, $inc_height, $img_type] = getimagesize($filename) ?: [];
$thumbnail_write_path = null;
$thumbnail_web_path = null;
// path set first
if (
$img_type == IMAGETYPE_JPEG ||
$img_type == IMAGETYPE_PNG ||
$create_dummy === true
) {
// $this->debug('IMAGE PREPARE', "IMAGE TYPE OK: ".$inc_width.'x'.$inc_height);
// set thumbnail paths
$thumbnail_write_path = BASE . LAYOUT . CONTENT_PATH . CACHE . IMAGES;
$thumbnail_web_path = LAYOUT . CACHE . IMAGES;
// if images folder in cache does not exist create it, if failed, fall back to base cache folder
if (!is_dir($thumbnail_write_path)) {
if (false === mkdir($thumbnail_write_path)) {
$thumbnail_write_path = BASE . LAYOUT . CONTENT_PATH . CACHE;
$thumbnail_web_path = LAYOUT . CACHE;
}
}
}
// do resize or fall back on dummy run
if (
$img_type == IMAGETYPE_JPEG ||
$img_type == IMAGETYPE_PNG
) {
// if missing width or height in thumb, use the set one
if ($thumb_width == 0) {
$thumb_width = $inc_width;
}
if ($thumb_height == 0) {
$thumb_height = $inc_height;
}
// check resize parameters
if ($inc_width > $thumb_width || $inc_height > $thumb_height) {
$thumb_width_r = 0;
$thumb_height_r = 0;
// we need to keep the aspect ration on longest side
if (
($inc_height > $inc_width &&
// and the height is bigger than thumb set
$inc_height > $thumb_height) ||
// or the height is smaller or equal width
// but the width for the thumb is equal to the image height
($inc_height <= $inc_width &&
$inc_width == $thumb_width
)
) {
// $this->debug('IMAGE PREPARE', 'HEIGHT > WIDTH');
$ratio = $inc_height / $thumb_height;
$thumb_width_r = (int)ceil($inc_width / $ratio);
$thumb_height_r = $thumb_height;
} else {
// $this->debug('IMAGE PREPARE', 'WIDTH > HEIGHT');
$ratio = $inc_width / $thumb_width;
$thumb_width_r = $thumb_width;
$thumb_height_r = (int)ceil($inc_height / $ratio);
}
// $this->debug('IMAGE PREPARE', "Ratio: $ratio, Target size $thumb_width_r x $thumb_height_r");
// set output thumbnail name
$thumbnail = 'thumb-' . pathinfo($filename)['filename'] . '-'
. $thumb_width_r . 'x' . $thumb_height_r;
if (
$use_cache === false ||
!file_exists($thumbnail_write_path . $thumbnail)
) {
// image, copy source image, offset in image, source x/y, new size, source image size
$thumb = imagecreatetruecolor($thumb_width_r, $thumb_height_r);
if ($thumb === false) {
return false;
}
if ($img_type == IMAGETYPE_PNG) {
$imagecolorallocatealpha = imagecolorallocatealpha($thumb, 0, 0, 0, 127);
if ($imagecolorallocatealpha === false) {
return false;
}
// preservere transaprency
imagecolortransparent(
$thumb,
$imagecolorallocatealpha
);
imagealphablending($thumb, false);
imagesavealpha($thumb, true);
}
$source = null;
switch ($img_type) {
case IMAGETYPE_JPEG:
$source = imagecreatefromjpeg($filename);
break;
case IMAGETYPE_PNG:
$source = imagecreatefrompng($filename);
break;
}
// check that we have a source image resource
if ($source !== null && $source !== false) {
// resize no shift
if ($high_quality === true) {
imagecopyresized(
$thumb,
$source,
0,
0,
0,
0,
$thumb_width_r,
$thumb_height_r,
$inc_width,
$inc_height
);
} else {
imagecopyresampled(
$thumb,
$source,
0,
0,
0,
0,
$thumb_width_r,
$thumb_height_r,
$inc_width,
$inc_height
);
}
// write file
switch ($img_type) {
case IMAGETYPE_JPEG:
imagejpeg($thumb, $thumbnail_write_path . $thumbnail, $jpeg_quality);
break;
case IMAGETYPE_PNG:
imagepng($thumb, $thumbnail_write_path . $thumbnail);
break;
}
// free up resources (in case we are called in a loop)
imagedestroy($source);
imagedestroy($thumb);
} else {
$thumbnail = false;
}
}
} else {
// we just copy over the image as is, we never upscale
$thumbnail = 'thumb-' . pathinfo($filename)['filename'] . '-' . $inc_width . 'x' . $inc_height;
if (
$use_cache === false ||
!file_exists($thumbnail_write_path . $thumbnail)
) {
copy($filename, $thumbnail_write_path . $thumbnail);
}
}
// add output path
if ($thumbnail !== false) {
$thumbnail = $thumbnail_web_path . $thumbnail;
}
} elseif ($create_dummy === true) {
// create dummy image in the thumbnail size
// if one side is missing, use the other side to create a square
if (!$thumb_width) {
$thumb_width = $thumb_height;
}
if (!$thumb_height) {
$thumb_height = $thumb_width;
}
// do we have an image already?
$thumbnail = 'thumb-' . pathinfo($filename)['filename'] . '-' . $thumb_width . 'x' . $thumb_height;
if (
$use_cache === false ||
!file_exists($thumbnail_write_path . $thumbnail)
) {
// if both are unset, set to 250
if ($thumb_height == 0) {
$thumb_height = 250;
}
if ($thumb_width == 0) {
$thumb_width = 250;
}
$thumb = imagecreatetruecolor($thumb_width, $thumb_height);
if ($thumb === false) {
return false;
}
// add outside border px = 5% (rounded up)
// eg 50px -> 2.5px
$gray = imagecolorallocate($thumb, 200, 200, 200);
$white = imagecolorallocate($thumb, 255, 255, 255);
if ($gray === false || $white === false) {
return false;
}
// fill gray background
imagefill($thumb, 0, 0, $gray);
// now create rectangle
if (imagesx($thumb) < imagesy($thumb)) {
$width = (int)round(imagesx($thumb) / 100 * 5);
} else {
$width = (int)round(imagesy($thumb) / 100 * 5);
}
imagefilledrectangle(
$thumb,
0 + $width,
0 + $width,
imagesx($thumb) - $width,
imagesy($thumb) - $width,
$white
);
// add "No valid images source"
// OR add circle
// * find center
// * width/height is 75% of size - border
// smaller size is taken
$base_width = imagesx($thumb) > imagesy($thumb) ? imagesy($thumb) : imagesx($thumb);
// get 75% width
$cross_width = (int)round((($base_width - ($width * 2)) / 100 * 75) / 2);
$center_x = (int)round(imagesx($thumb) / 2);
$center_y = (int)round(imagesy($thumb) / 2);
imagefilledellipse($thumb, $center_x, $center_y, $cross_width, $cross_width, $gray);
// find top left and bottom left for first line
imagepng($thumb, $thumbnail_write_path . $thumbnail);
}
// add web path
$thumbnail = $thumbnail_web_path . $thumbnail;
}
}
// either return false or the thumbnail name + output path web
return $thumbnail;
}
/**
* reads the rotation info of an file and rotates it to be correctly upright
* this is done because not all software honers the exit Orientation flag
* only works with jpg or png
*
* @param string $filename path + filename to rotate. This file must be writeable
* @return void
*/
public static function correctImageOrientation($filename): void
{
// function exists & file is writeable, else do nothing
if (!function_exists('exif_read_data') || !is_writeable($filename)) {
return;
}
[$inc_width, $inc_height, $img_type] = getimagesize($filename) ?: [];
// add @ to avoid "file not supported error"
$exif = @exif_read_data($filename);
$orientation = null;
$img = null;
if ($exif && isset($exif['Orientation'])) {
$orientation = $exif['Orientation'];
}
// only if we need to rotate, if 1 it is already upright
if ($orientation === null || $orientation == 1) {
return;
}
switch ($img_type) {
case IMAGETYPE_JPEG:
$img = imagecreatefromjpeg($filename);
break;
case IMAGETYPE_PNG:
$img = imagecreatefrompng($filename);
break;
}
// no image loaded (wrong type)
if ($img === null || $img === false) {
return;
}
$deg = 0;
// 1 top, 6: left, 8: right, 3: bottom
switch ($orientation) {
case 3:
$deg = 180;
break;
case 6:
$deg = -90;
break;
case 8:
$deg = 90;
break;
}
// rotate if needed
if ($deg) {
$img = imagerotate($img, $deg, 0);
}
// rotate failed
if ($img === false) {
return;
}
// then rewrite the rotated image back to the disk as $filename
switch ($img_type) {
case IMAGETYPE_JPEG:
imagejpeg($img, $filename);
break;
case IMAGETYPE_PNG:
imagepng($img, $filename);
break;
}
// clean up image if we have an image
imagedestroy($img);
}
}
// __END__

932
src/Output/ProgressBar.php Normal file
View File

@@ -0,0 +1,932 @@
<?php
/*
* Class ProgressBar
*
* Author: Gerd Weitenberg (hahnebuechen@web.de)
* Date: 2005.03.09
*
* Update: Clemens Schwaighofer
* Date: 2012.9.5 [stacked output]
* Date: 2013.2.21 [proper class formatting]
* Date: 2017.4.13 [no output fix with cache overload]
* Date: 2018.3.28 [PHPCS + namespace]
*
*/
declare(strict_types=1);
namespace CoreLibs\Output;
class ProgressBar
{
// private vars
/** @var string */
public $code; // unique code
/** @var string */
public $status = 'new'; // current status (new,show,hide)
/** @var float|int */
public $step = 0; // current step
/** @var array<string,null|int|float> */
public $position = [ // current bar position
'left' => null,
'top' => null,
'width' => null,
'height' => null,
];
/** @var int */
public $clear_buffer_size = 1; // we need to send this before the lfush to get browser output
/** @var int */
public $clear_buffer_size_init = 1024 * 1024; // if I don't send that junk, it won't send anything
// public vars
/** @var int */
public $min = 0; // minimal steps
/** @var int */
public $max = 100; // maximal steps
/** @var int */
public $left = 5; // bar position from left
/** @var int */
public $top = 5; // bar position from top
/** @var int */
public $width = 300; // bar width
/** @var int */
public $height = 25; // bar height
/** @var int */
public $pedding = 0; // bar pedding
/** @var string */
public $color = '#0033ff'; // bar color
/** @var string */
public $bgr_color = '#c0c0c0'; // bar background color
/** @var string */
public $bgr_color_master = '#ffffff'; // master div background color
/** @var int */
public $border = 1; // bar border width
/** @var string */
public $brd_color = '#000000'; // bar border color
/** @var string */
public $direction = 'right'; // direction of motion (right,left,up,down)
/** @var array<string,string|bool|int> */
public $frame = ['show' => false]; // ProgressBar Frame
/* 'show' => false, # frame show (true/false)
'left' => 200, # frame position from left
'top' => 100, # frame position from top
'width' => 300, # frame width
'height' => 75, # frame height
'color' => '#c0c0c0', # frame color
'border' => 2, # frame border
'brd_color' => '#dfdfdf #404040 #404040 #dfdfdf' # frame border color
*/
/** @#var array{string}{string: string|int} */
/** @var mixed[][] */
public $label = []; // ProgressBar Labels
/* 'name' => [ # label name
'type' => 'text', # label type (text,button,step,percent,crossbar)
'value' => 'Please wait ...', # label value
'left' => 10, # label position from left
'top' => 20, # label position from top
'width' => 0, # label width
'height' => 0, # label height
'align' => 'left', # label align
'font-size' => 11, # label font size
'font-family' => 'Verdana, Tahoma, Arial', # label font family
'font-weight' => '', # label font weight
'color' => '#000000', # label font color
'bgr_color' => '' # label background color
]
*/
/** @var string */
// output strings
public $prefix_message = '';
/**
* progress bar constructor
*
* @param integer $width progress bar width, default 0
* @param integer $height progress bar height, default 0
*/
public function __construct(int $width = 0, int $height = 0)
{
$this->code = substr(md5(microtime()), 0, 6);
if ($width > 0) {
$this->width = $width;
}
if ($height > 0) {
$this->height = $height;
}
// needs to be called twice or I do not get any output
$this->__flushCache($this->clear_buffer_size_init);
$this->__flushCache($this->clear_buffer_size_init);
}
// private functions
/**
* flush cache hack for IE and others
*
* @param integer $clear_buffer_size buffer size override
* @return void has not return
*/
private function __flushCache(int $clear_buffer_size = 0): void
{
if (!$clear_buffer_size) {
$clear_buffer_size = $this->clear_buffer_size;
}
echo str_repeat(' ', $clear_buffer_size);
// a small hack to avoid warnings about no buffer to flush
@ob_flush();
flush();
}
/**
* [__calculatePercent description]
*
* @param float $step percent step to do
* @return float percent step done
*/
private function __calculatePercent(float $step): float
{
// avoid divison through 0
if ($this->max - $this->min == 0) {
$this->max ++;
}
$percent = round(($step - $this->min) / ($this->max - $this->min) * 100);
if ($percent > 100) {
$percent = 100;
}
return $percent;
}
/**
* calculate position in bar step
*
* @param float $step percent step to do
* @return array<string,int|float> bar position as array
*/
private function __calculatePosition(float $step): array
{
$bar = 0;
switch ($this->direction) {
case 'right':
case 'left':
$bar = $this->width;
break;
case 'down':
case 'up':
$bar = $this->height;
break;
}
// avoid divison through 0
if ($this->max - $this->min == 0) {
$this->max ++;
}
$pixel = round(($step - $this->min) * ($bar - ($this->pedding * 2)) / ($this->max - $this->min));
if ($step <= $this->min) {
$pixel = 0;
}
if ($step >= $this->max) {
$pixel = $bar - ($this->pedding * 2);
}
$position = [];
switch ($this->direction) {
case 'right':
$position['left'] = $this->pedding;
$position['top'] = $this->pedding;
$position['width'] = $pixel;
$position['height'] = $this->height - ($this->pedding * 2);
break;
case 'left':
$position['left'] = $this->width - $this->pedding - $pixel;
$position['top'] = $this->pedding;
$position['width'] = $pixel;
$position['height'] = $this->height - ($this->pedding * 2);
break;
case 'down':
$position['left'] = $this->pedding;
$position['top'] = $this->pedding;
$position['width'] = $this->width - ($this->pedding * 2);
$position['height'] = $pixel;
break;
case 'up':
$position['left'] = $this->pedding;
$position['top'] = $this->height - $this->pedding - $pixel;
$position['width'] = $this->width - ($this->pedding * 2);
$position['height'] = $pixel;
break;
}
return $position;
}
/**
* set the step
*
* @param float $step percent step to do
* @return void
*/
private function __setStep(float $step): void
{
if ($step > $this->max) {
$step = $this->max;
}
if ($step < $this->min) {
$step = $this->min;
}
$this->step = $step;
}
// public functions
/**
* set frame layout
*
* @param integer $width bar width
* @param integer $height bar height
* @return void
*/
public function setFrame(int $width = 0, int $height = 0): void
{
$this->frame = [
'show' => true,
'left' => 20,
'top' => 35,
'width' => $this->width + 6,
'height' => 'auto',
'color' => '#c0c0c0',
'border' => 2,
'brd_color' => '#dfdfdf #404040 #404040 #dfdfdf'
];
if ($width > 0) {
$this->frame['width'] = $width;
}
if ($height > 0) {
$this->frame['height'] = $height;
}
}
/**
* set bar label text
* allowed types are: text, button, step, percent, percentlbl, crossbar
*
* @param string $type label type
* @param string $name label name (internal)
* @param string $value label output name (optional)
* @return void
*/
public function addLabel(string $type, string $name, string $value = '&nbsp;'): void
{
switch ($type) {
case 'text':
$this->label[$name] = [
'type' => 'text',
'value' => $value,
'left' => 0, // keep all to the left in box
'top' => 2, // default top is 2px
'width' => $this->width,
'height' => 0,
'align' => 'left',
'font-size' => 11,
'font-family' => 'Verdana, Tahoma, Arial',
'font-weight' => 'normal',
'color' => '#000000',
'bgr_color' => ''
];
break;
case 'button':
$this->label[$name] = [
'type' => 'button',
'value' => $value,
'action' => '',
'target' => 'self',
'left' => 5,
'top' => 5,
'width' => 0,
'height' => 0,
'align' => 'center',
'font-size' => 11,
'font-family' => 'Verdana, Tahoma, Arial',
'font-weight' => 'normal',
'color' => '#000000',
'bgr_color' => ''
];
break;
case 'step':
$this->label[$name] = [
'type' => 'step',
'value' => $value,
'left' => $this->left + 5,
'top' => $this->top + 5,
'width' => 10,
'height' => 0,
'align' => 'right',
'font-size' => 11,
'font-family' => 'Verdana, Tahoma, Arial',
'font-weight' => 'normal',
'color' => '#000000',
'bgr_color' => ''
];
break;
case 'percentlbl':
case 'percent':
// check font size
if ($this->height <= 11) {
$font_size = $this->height - 1;
} else {
$font_size = 11;
}
$this->label[$name] = [
'type' => $type, // either percent or percentlbl
'value' => $value,
'left' => false,
'top' => round(
($this->height - $font_size) / log($this->height - $font_size, 7),
0
) - $this->pedding,
'width' => $this->width,
'height' => 0,
'align' => 'center',
'font-size' => $font_size,
'font-family' => 'sans-serif',
'font-weight' => 'normal',
'color' => '#000000',
'bgr_color' => ''
];
break;
case 'crossbar':
$this->label[$name] = [
'type' => 'crossbar',
'value' => $value,
'left' => $this->left + ($this->width / 2),
'top' => $this->top - 16,
'width' => 10,
'height' => 0,
'align' => 'center',
'font-size' => 11,
'font-family' => 'Verdana, Tahoma, Arial',
'font-weight' => 'normal',
'color' => '#000000',
'bgr_color' => ''
];
break;
}
}
/**
* add a button to the progress bar
*
* @param string $name button name (internal)
* @param string $value button text (output)
* @param string $action button action (link)
* @param string $target button action target (default self)
* @return void
*/
public function addButton(string $name, string $value, string $action, string $target = 'self'): void
{
$this->addLabel('button', $name, $value);
$this->label[$name]['action'] = $action;
$this->label[$name]['target'] = $target;
}
/**
* set the label position
*
* @param string $name label name to set
* @param int $left left px
* @param int $top top px
* @param int $width width px
* @param int $height height px
* @param string $align alignment (left/right/etc), default empty
* @return void
*/
public function setLabelPosition(
string $name,
int $left,
int $top,
int $width,
int $height,
string $align = ''
): void {
// print "SET POSITION[$name]: $left<br>";
// if this is percent, we ignore anything, it is auto positioned
if ($this->label[$name]['type'] != 'percent') {
foreach (['top', 'left', 'width', 'height'] as $pos_name) {
if ($$pos_name !== false) {
$this->label[$name][$pos_name] = intval($$pos_name);
}
}
if ($align != '') {
$this->label[$name]['align'] = $align;
}
}
// init
if ($this->status != 'new') {
$output = '<script type="text/JavaScript">';
$output .= 'document.getElementById("plbl' . $name
. $this->code . '").style.top="' . $this->label[$name]['top'] . 'px";';
$output .= 'document.getElementById("plbl' . $name
. $this->code . '").style.left="' . $this->label[$name]['left'] . 'px";';
$output .= 'document.getElementById("plbl' . $name
. $this->code . '").style.width="' . $this->label[$name]['width'] . 'px";';
$output .= 'document.getElementById("plbl' . $name
. $this->code . '").style.height="' . $this->label[$name]['height'] . 'px";';
$output .= 'document.getElementById("plbl' . $name
. $this->code . '").style.align="' . $this->label[$name]['align'] . '";';
$output .= '</script>' . "\n";
echo $output;
$this->__flushCache();
}
}
/**
* set label color
*
* @param string $name label name to set
* @param string $color color value in rgb html hex
* @return void
*/
public function setLabelColor(string $name, string $color): void
{
$this->label[$name]['color'] = $color;
if ($this->status != 'new') {
echo '<script type="text/JavaScript">document.getElementById("plbl' . $name
. $this->code . '").style.color="' . $color . '";</script>' . "\n";
$this->__flushCache();
}
}
/**
* set the label background color
*
* @param string $name label name to set
* @param string $color background color to set in rgb html hex
* @return void
*/
public function setLabelBackground(string $name, string $color): void
{
$this->label[$name]['bgr_color'] = $color;
if ($this->status != 'new') {
echo '<script type="text/JavaScript">document.getElementById("plbl' . $name
. $this->code . '").style.background="' . $color . '";</script>' . "\n";
$this->__flushCache();
}
}
/**
* [setLabelFont description]
*
* @param string $name label name to set
* @param int $size font size in px
* @param string $family font family (default empty)
* @param string $weight font weight (default empty)
* @return void
*/
public function setLabelFont(string $name, int $size, string $family = '', string $weight = ''): void
{
// just in case if it is too small
if (intval($size) < 0) {
$size = 11;
}
// if this is percent, the size is not allowed to be bigger than the bar size - 5px
if ($this->label[$name]['type'] == 'percent' && intval($size) >= $this->height) {
$size = $this->height - 1;
}
// position the label new if this is percent
if ($this->label[$name]['type'] == 'percent') {
$this->label[$name]['top'] = round(
($this->height - intval($size)) / log($this->height - intval($size), 7),
0
) - $this->pedding;
}
// print "HEIGHT: ".$this->height.", Size: ".intval($size)
// .", Pedding: ".$this->pedding.", Calc: ".round($this->height - intval($size))
// .", Log: ".log($this->height - intval($size), 7)."<br>";
// then set like usual
$this->label[$name]['font-size'] = intval($size);
if ($family != '') {
$this->label[$name]['font-family'] = $family;
}
if ($weight != '') {
$this->label[$name]['font-weight'] = $weight;
}
if ($this->status != 'new') {
$output = '<script type="text/JavaScript">';
$output .= 'document.getElementById("plbl' . $name
. $this->code . '").style.font-size="' . $this->label[$name]['font-size'] . 'px";';
$output .= 'document.getElementById("plbl' . $name
. $this->code . '").style.font-family="' . $this->label[$name]['font-family'] . '";';
$output .= 'document.getElementById("plbl' . $name
. $this->code . '").style.font-weight="' . $this->label[$name]['font-weight'] . '";';
$output .= '</script>' . "\n";
echo $output;
$this->__flushCache();
}
}
/**
* set the label value
*
* @param string $name label name to set
* @param string $value label value (output)
* @return void
*/
public function setLabelValue(string $name, string $value): void
{
$this->label[$name]['value'] = $value;
// print "NAME[$name], Status: ".$this->status.": ".$value."<Br>";
if ($this->status != 'new') {
echo '<script type="text/JavaScript">PBlabelText' . $this->code
. '("' . $name . '","' . $this->label[$name]['value'] . '");</script>' . "\n";
$this->__flushCache();
}
}
/**
* set the bar color
*
* @param string $color color for the progress bar in rgb html hex
* @return void
*/
public function setBarColor(string $color): void
{
$this->color = $color;
if ($this->status != 'new') {
echo '<script type="text/JavaScript">document.getElementById("pbar' . $this->code
. '").style.background="' . $color . '";</script>' . "\n";
$this->__flushCache();
}
}
/**
* set the progress bar background color
*
* @param string $color background color in rgb html hex
* @return void
*/
public function setBarBackground(string $color): void
{
$this->bgr_color = $color;
if ($this->status != 'new') {
echo '<script type="text/JavaScript">document.getElementById("pbrd' . $this->code
. '").style.background="' . $color . '";</script>' . "\n";
$this->__flushCache();
}
}
/**
* progress bar direct (left/right)
*
* @param string $direction set direction as left/right
* @return void
*/
public function setBarDirection(string $direction): void
{
$this->direction = $direction;
if ($this->status != 'new') {
$this->position = $this->__calculatePosition($this->step);
echo '<script type="text/JavaScript">';
echo 'PBposition' . $this->code . '("left",' . $this->position['left'] . ');';
echo 'PBposition' . $this->code . '("top",' . $this->position['top'] . ');';
echo 'PBposition' . $this->code . '("width",' . $this->position['width'] . ');';
echo 'PBposition' . $this->code . '("height",' . $this->position['height'] . ');';
echo '</script>' . "\n";
$this->__flushCache();
}
}
/**
* get the progress bar base HTML
*
* @return string progress bar HTML code
*/
public function getHtml(): string
{
$html = '';
$js = '';
$html_button = '';
$html_percent = '';
$this->__setStep($this->step);
$this->position = $this->__calculatePosition($this->step);
$style_master = '';
if ($this->top || $this->left) {
$style_master = 'position:relative;top:' . $this->top
. 'px;left:' . $this->left . 'px;width:' . ($this->width + 10) . 'px;';
}
$html = '<div id="pbm' . $this->code . '" style="' . $style_master
. 'background:' . $this->bgr_color_master . ';">';
$style_brd = 'width:' . $this->width . 'px;height:' . $this->height
. 'px;background:' . $this->bgr_color . ';';
if ($this->border > 0) {
$style_brd .= 'border:'
. $this->border . 'px solid; border-color:'
. $this->brd_color . '; -webkit-border-radius: 5px 5px 5px 5px; '
. 'border-radius: 5px 5px 5px 5px; -webkit-shadow: 2px 2px 10px rgba(0, 0, 0, 0.25) inset; '
. 'box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.25) inset;';
}
$style_bar = 'position:relative;width:' . $this->position['width']
. 'px;height:' . $this->position['height'] . 'px;background:' . $this->color . ';';
if ($this->position['top'] !== false) {
$style_bar .= 'top:' . $this->position['top'] . 'px;';
}
if ($this->position['left'] !== false) {
$style_bar .= 'left:' . $this->position['left'] . 'px;';
}
if ($this->border > 0) {
$style_bar .= '-webkit-border-radius: 5px 5px 5px 5px; '
. 'border-radius: 5px 5px 5px 5px; -webkit-shadow: 2px 2px 10px rgba(0, 0, 0, 0.25) inset; '
. 'box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.25) inset;';
}
if ($this->frame['show'] == true) {
$border = '';
if ($this->frame['border'] > 0) {
$border = 'border:' . $this->frame['border']
. 'px solid;border-color:' . $this->frame['brd_color'] . ';margin-top:2px; '
. '-webkit-border-radius: 5px 5px 5px 5px; border-radius: 5px 5px 5px 5px;';
}
$html .= '<div id="pfrm' . $this->code . '" style="width:'
. $this->frame['width'] . 'px;height:' . $this->frame['height'] . 'px;'
. $border . 'background:' . $this->frame['color'] . ';">' . "\n";
}
// temp write the bar here, we add that later, below all the html + progress %
$html_bar_top = '<div id="pbrd' . $this->code . '" style="' . $style_brd
. ($this->frame['show'] == true ? 'margin-left: 2px;margin-bottom:2px;' : '') . '">' . "\n";
$html_bar_top .= '<div id="pbar' . $this->code . '" style="' . $style_bar . '">';
// insert single percent there
$html_bar_bottom = '</div></div>' . "\n";
$js .= 'function PBposition' . $this->code . '(item,pixel) {' . "\n";
$js .= ' pixel = parseInt(pixel);' . "\n";
$js .= ' switch(item) {' . "\n";
$js .= ' case "left": document.getElementById("pbar' . $this->code
. '").style.left=(pixel) + \'px\'; break;' . "\n";
$js .= ' case "top": document.getElementById("pbar' . $this->code
. '").style.top=(pixel) + \'px\'; break;' . "\n";
$js .= ' case "width": document.getElementById("pbar' . $this->code
. '").style.width=(pixel) + \'px\'; break;' . "\n";
$js .= ' case "height": document.getElementById("pbar' . $this->code
. '").style.height=(pixel) + \'px\'; break;' . "\n";
$js .= ' }' . "\n";
$js .= '}' . "\n";
// print "DUMP LABEL: <br><pre>".print_r($this->label, true)."</pre><br>";
foreach ($this->label as $name => $data) {
// set what type of move we do
$move_prefix = $data['type'] == 'button' ? 'margin' : 'padding';
$style_lbl = 'position:relative;';
if ($data['top'] !== false) {
$style_lbl .= $move_prefix . '-top:' . $data['top'] . 'px;';
}
if ($data['left'] !== false) {
$style_lbl .= $move_prefix . '-left:' . $data['left'] . 'px;';
}
$style_lbl .= 'text-align:' . $data['align'] . ';';
if ($data['width'] > 0) {
$style_lbl .= 'width:' . $data['width'] . 'px;';
}
if ($data['height'] > 0) {
$style_lbl .= 'height:' . $data['height'] . 'px;';
}
if (array_key_exists('font-size', $data)) {
$style_lbl .= 'font-size:' . $data['font-size'] . 'px;';
}
if (array_key_exists('font-family', $data)) {
$style_lbl .= 'font-family:' . $data['font-family'] . ';';
}
if (array_key_exists('font-weight', $data)) {
$style_lbl .= 'font-weight:' . $data['font-weight'] . ';';
}
if (array_key_exists('bgr_color', $data) && ($data['bgr_color'] != '')) {
$style_lbl .= 'background:' . $data['bgr_color'] . ';';
}
if (array_key_exists('type', $data)) {
switch ($data['type']) {
case 'text':
$html .= '<div id="plbl' . $name . $this->code . '" style="'
. $style_lbl . 'margin-bottom:2px;">' . $data['value'] . '</div>' . "\n";
break;
case 'button':
$html_button .= '<div><input id="plbl' . $name
. $this->code . '" type="button" value="' . $data['value'] . '" style="'
. $style_lbl . 'margin-bottom:5px;" onclick="' . $data['target'] . '.location.href=\''
. $data['action'] . '\'" /></div>' . "\n";
break;
case 'step':
$html .= '<div id="plbl' . $name . $this->code . '" style="'
. $style_lbl . '">' . $this->step . '</div>' . "\n";
break;
case 'percent':
// only one inner percent
// print "STYLE[$name]: ".$style_lbl."<br>";
if (empty($html_percent)) {
$html_percent = '<div id="plbl' . $name . $this->code
. '" style="' . $style_lbl . 'width:' . $data['width']
. 'px;line-height:1;text-shadow: 0 0 .2em white, 0 0 .5em white;">'
. $this->__calculatePercent($this->step) . '%</div>' . "\n";
}
break;
case 'percentlbl':
$html .= '<div id="plbl' . $name . $this->code . '" style="'
. $style_lbl . 'width:' . $data['width'] . 'px;">'
. $this->__calculatePercent($this->step) . '%</div>' . "\n";
break;
case 'crossbar':
$html .= '<div id="plbl' . $name . $this->code . '" style="'
. $style_lbl . '">' . $data['value'] . '</div>' . "\n";
$js .= 'function PBrotaryCross' . $name . $this->code . '() {'
. "\n"
. ' cross = document.getElementById("plbl' . $name
. $this->code . '").firstChild.nodeValue;' . "\n"
. ' switch(cross) {' . "\n"
. ' case "--": cross = "\\\\"; break;' . "\n"
. ' case "\\\\": cross = "|"; break;' . "\n"
. ' case "|": cross = "/"; break;' . "\n"
. ' default: cross = "--"; break;' . "\n"
. ' }' . "\n"
. ' document.getElementById("plbl' . $name
. $this->code . '").firstChild.nodeValue = cross;' . "\n"
. '}' . "\n";
break;
}
}
}
// write the progress bar + inner percent inside
$html .= $html_bar_top;
$html .= $html_percent;
$html .= $html_bar_bottom;
$html .= $html_button; // any buttons on bottom
if (count($this->label) > 0) {
$js .= 'function PBlabelText' . $this->code . '(name,text) {' . "\n";
$js .= ' name = "plbl" + name + "' . $this->code . '";' . "\n";
$js .= ' document.getElementById(name).innerHTML=text;' . "\n";
$js .= '}' . "\n";
}
if ($this->frame['show'] == true) {
$html .= '</div>' . "\n";
}
$html .= '<script type="text/JavaScript">' . "\n";
$html .= $js;
$html .= '</script>' . "\n";
$html .= '</div>';
return $html;
}
/**
* show the progress bar after initialize
*
* @return void has no return
*/
public function show(): void
{
$this->status = 'show';
echo $this->getHtml();
$this->__flushCache();
}
/**
* move the progress bar by one step
* prints out javascript to move progress bar
*
* @param float $step percent step
* @return void has no return
*/
public function moveStep(float $step): void
{
$last_step = $this->step;
$this->__setStep($step);
$js = '';
$new_position = $this->__calculatePosition($this->step);
if (
$new_position['width'] != $this->position['width'] &&
($this->direction == 'right' || $this->direction == 'left')
) {
if ($this->direction == 'left') {
$js .= 'PBposition' . $this->code . '("left",' . $new_position['left'] . ');';
}
$js .= 'PBposition' . $this->code . '("width",' . $new_position['width'] . ');';
}
if (
$new_position['height'] != $this->position['height'] &&
($this->direction == 'up' || $this->direction == 'down')
) {
if ($this->direction == 'up') {
$js .= 'PBposition' . $this->code . '("top",' . $new_position['top'] . ');';
}
$js .= 'PBposition' . $this->code . '("height",' . $new_position['height'] . ');';
}
$this->position = $new_position;
foreach ($this->label as $name => $data) {
if (array_key_exists('type', $data)) {
switch ($data['type']) {
case 'step':
if ($this->step != $last_step) {
$js .= 'PBlabelText' . $this->code . '("'
. $name . '","' . $this->step . '/' . $this->max . '");';
}
break;
case 'percentlbl':
case 'percent':
$percent = $this->__calculatePercent($this->step);
if ($percent != $this->__calculatePercent($last_step)) {
$js .= 'PBlabelText' . $this->code . '("' . $name . '","' . $percent . '%");';
}
break;
case 'crossbar':
$js .= 'PBrotaryCross' . $name . $this->code . '();';
break;
}
}
}
if ($js != '') {
echo '<script type="text/JavaScript">' . $js . '</script>' . "\n";
$this->__flushCache();
}
}
/**
* moves progress bar by one step (1)
*
* @return void has no return
*/
public function moveNext(): void
{
$this->moveStep($this->step + 1);
}
/**
* moves the progress bar back to the beginning
*
* @return void has no return
*/
public function moveMin(): void
{
$this->moveStep($this->min);
}
/**
* hide the progress bar if it is visible
*
* @return void has no return
*/
public function hide(): void
{
if ($this->status == 'show') {
$this->status = 'hide';
$output = '<script type="text/JavaScript">'
. 'document.getElementById("pbm' . $this->code
. '").style.visibility="hidden";document.getElementById("pbm'
. $this->code . '").style.display="none";'
. '</script>' . "\n";
echo $output;
$this->__flushCache();
}
}
/**
* show progress bar again after it was hidden with hide()
*
* @return void has no return
*/
public function unhide(): void
{
if ($this->status == 'hide') {
$this->status = 'show';
$output = '<script type="text/JavaScript">'
. 'document.getElementById("pbm' . $this->code
. '").style.visibility="visible";document.getElementById("pbm'
. $this->code . '").style.visibility="block";'
. '</script>' . "\n";
echo $output;
$this->__flushCache();
}
}
}
// __END__

View File

@@ -0,0 +1,16 @@
<?php
declare(strict_types=1);
namespace CoreLibs\Output\Form;
interface TableArraysInterface
{
/**
* setTableArray interface, set the table array
* @return array<mixed>
*/
public function setTableArray(): array;
}
// __END__