.. include:: definitions.txt ******************************************** PHP, HTML/JavaScript, MySQL code description ******************************************** * This manual is created with `Sphinx `_. * Python version: * On local test server (XAMPP - server): 2.7.15 (installation package :file:`C:\\Dany\\Software\\Python\\python-2.7.15.msi`) * Python Documentation Generator: `Sphinx Documentation (pdf) `_. * Quick manual: `reStructuredText from Sphinx - org `_ , and `alternative link `_ * Quick manual: `reStructuredText Directives from Sphinx - org `_, and `alternative Directives link `_. * Quick manual: `reStructuredText Roles from Sphinx - org `_, and `alternative Roles link `_. * **Sphinx** is installed in :file:`C:\\Python27\\Lib\\site-packages\\sphinx`. * **Sphinx**: document build `configuration file `_. * **Sphinx** extensions, add-ons which come with a :file:`setup.py` file, are installed with the following command: :command:`py setup.py build`, in the directory containing the :file:`setup.py` file. * Manual makes use of theme and extensions: * the `Cloud `_ theme. **Cloud theme** is installed in :file:`C:\\Python27\\Lib\\site-packages\\cloud_sptheme`, and must be included as extension in the configuration file :file:`conf.py`. Different HTML theme flavors can be selected. The selected HTML theme flavor is **cloud**, and the default settings of this theme are implemented in :file:`C:\\Python27\\Lib\\site-packages\\cloud_sptheme\\themes\\cloud\\theme.conf`. Deviations from the default settings can be set in :file:`conf.py` (:command:`html_theme_options = {'externalrefs':'false'}`) * the `PHP domain `_. (For domain: see `link `_) The code manual of the website can be called from the website itself when: * Website is running from a local server for any user (for development purposes), i.e from host address 127.0.0.1, * Or user admin is logged on to the website running on a ISP webserver, **and** * :phpc:`$albumDirThumbStatHtml['server_info']['debugJS'] = true` in :file:`/php/prepareDirOverviewGalleryAjax.php`. See also :numref:`table_server_info`. This is implemented for debugging and test purposes. * Public :phpc:`debug` member in class :phpc:`sqlConnectFail`, which is defined in |loginFunctions.php|, is set to true (by setting :phpc:`DEBUG` macro in |filesystem.php|). The manual can be called from the following locations: * Main menubar, * :ref:`Media Processing Status dialog window `. The manual button in each tab in the **Media Processing Status dialog window** refers to a different location in the manual. Note on text and link format ============================ * :command:`command` (role :command:`:command:`), * :phpc:`code lines, and code fragments in PHP` (role :command:`:phpc:`), * :php:`Links to internal PHP functions`. PHP domain: * Definition: role :command:`:php:function:`, * Reference: role :command:`:php:func:`, * :php:`PHP files` (PHP domain |r_arrow| role :command:`:php:`), * :php:`Links to internal PHP files`. PY domain: * Definition: role :command:`:py:module:`, * Reference: role :command:`:py:mod:`, * :js:`Links to internal Javascript functions`. JS domain: * Definition: role :command:`:js:function:`, * Reference: role :command:`:js:func:`, General ======= The website makes use of the following languages: * PHP, MySQL (A2hosting: version 7.0, localhost: version 7.2.0), * HTML 5, * `JavaScript `_ * `Jquery `_ * `AJAX `_ CORS (Cross-Origin Resource Sharing) on PHP: is a mechanism that uses additional HTTP headers to tell a browser to let a web application running at one origin have permission to access selected resources from a server at a different origin. CORS headers: switch to https protocol if there is security certificate * $hs='Access-Control-Allow-Origin: '.__FILE__; header($hs); * .htaccess file Standard datafile formats used by the site ------------------------------------------ * JSON (JavaScript Object Notation) * XML (Extensible Markup Language) Regular expressions and filters ------------------------------- For matching media names, regular expressions are used. * Complete `manual `_ * Examples and explanation of syntax of regular expressions: https://support.google.com/a/answer/1371417?hl=en On this site useful examples are given for filtering e-mail addresses from given domains. * Testing regular expression: https://regex101.com/ Use of PHP array functions ========================== .. _sec_L3_array_walk: `array_walk `_ --------------------------------------------------------------------- Applies the user-defined callback function to each element of the `array `_ array. `array_walk() `_ is not affected by the internal array pointer of array. `array_walk() `_ will walk through the entire array regardless of pointer position. The `array_walk() `_ function is used with the following callback functions: * :phpc:`function aw_cb_single_val(&$value,$key,$updateVal){$value["XFFFFF"]|=$updateVal;}` In this callback function the :phpc:`$key` argument is not used. The result of the `array_walk() `_ function with this callback function is: for each array element: :phpc:`$XFFFFF_Arr[i][‘XFFFFF’] = $XFFFFF[‘GlobStat’]`. * :phpc:`function aw_cb_array_val(&$value,$key,$updateVal){$value["XFFFFF"]|=$updateVal[$key];}` The result of the array_walk function with this callback function is: for each array element: :phpc:`$XFFFFF_Arr[i][‘XFFFFF’] = $XFFFFF[‘GlobStat’]`. .. _sec_L3_array_column: `array_column `_ ------------------------------------------------------------------------- Function :phpc:`array array_column(array $input , mixed $column_key [, mixed $index_key = NULL])` returns the values from a single column of the :phpc:`$input` array, identified by the :phpc:`$column_key`. Function `array_column `_ is called in :php:func:`Mediacount_IMINFO_X0F000`. :phpc:`array_column($upd_media_dir,'modus');` where (:phpc:`$upd_media_dir` is matrix with 2 columns having the associative keys :phpc:`‘name’` and :phpc:`‘modus’`, respectively. The function will return the column :phpc:`‘modus’` of :phpc:`$upd_media_dir`. (For reference: in MATLAB such a function would not be needed: e.g. :command:`maxtrix(:,2)`) .. _sec_L3_in_array: `in_array `_ ----------------------------------------------------------------- .. _sec_L2_stdClass: stdClass object: how to avoid the list structure? ================================================= In PHP functions cannot return multiple output arguments. The effect of multiple output arguments can be implemented by returning an array. The return array must then be read with the PHP `list() `_ construct. But as the `PHP manual `_ issues a warning with respect to the use of list construct: "In PHP 5, list() assigns the values starting with the right-most parameter. In PHP 7, list() starts with the left-most parameter. If you are using plain variables, you don't have to worry about this. But if you are using arrays with indices you usually expect the order of the indices in the array the same you wrote in the list() from left to right, which is not the case in PHP 5, as it's assigned in the reverse order. Generally speaking, it is advisable to avoid relying on a specific order of operation, as this may change again in the future." For this reason the use of the list construct should be avoided. The PHP predefined built-in `stdClass object `_ (as of PHP 5.0) can be used as return object wrapper as an alternative for functions with array as return variable (as an implementation method for function with multiple output arguments). Filenames as input for PHP and Java script ========================================== Depending on the operating system running on the server and client (OS, Windows or Linux) filenames beginning with the character ‘#’ may or may not be accepted by the operating system. This leads to non-processing of the file and consequently to errors. In order to avoid these errors, rename these files by deleting the first character (‘#’). PHP packages ============ ZIP --- PHPMailer --------- * Reference: https://github.com/PHPMailer/PHPMailer * Dependencies, installation location: * |loginFunctions.php| * |remoteaddress.php| (external package: see :numref:`sec_L3_remote_address`) * :file:`/php/mailer/PHPMailerAutoload.php` * :file:`/php/mysql/encryption_decryption.php` * Called in: |e-mail.php| Responsive filemanager ---------------------- * Reference: http://www.responsivefilemanager.com * Version 9.9.7 * Installation location: :file:`/php/filemanager/dialog.php` * Called in template :file:`/Templates/41184-private.dwt` * Call instantiation: :js1:`window.open("php/filemanager/dialog.php?type=2&config=config_admin",'Media Filemanager',optstr);` * Configuration files: * :file:`/php/filemanager/config/config_normal_user.php` * :file:`/php/filemanager/config/config_admin.php` Encryption – Decryption ----------------------- * Defuse Security * Reference: https://github.com/defuse/php-encryption .. _sec_L3_getID3: GETID3: get exif data from video media files -------------------------------------------- Reference: http://getid3.sourceforge.net/ GETID3 array keys: :phpc:`[‘filesize’], [‘filepath’], [‘filename’], [‘filenamepath’], [‘avdataoffset’], [‘avdataend’], [‘fileformat’], [‘audio’][‘dataformat’], [‘audio’][‘codec’], [‘audio’][‘sample_rate’], [‘audio’][‘channels’], [‘audio’][‘bits_per_sample’]` .. _sec_L3_remote_address: Remote address (with respect to server) --------------------------------------- Functionality for determining client IP address. Since the information of the IP address is at the client side why not use JavaScript functions? (when client side makes use of a proxyserver?) .. _sec_L2_MYSQL: Server network configurations: MySQL and web ============================================ Server network configurations ----------------------------- .. _figure_SQL-WEB-on-ISP-host: .. figure:: Fig_SQL-WEB-on-ISP-host.png :width: 60% Normal website application: client and webserver are on different locations. In most cases, webserver and MySQL server are located on the same host. .. _figure_SQL-ISPhost-WEB-on-localhost: .. figure:: Fig_SQL-ISPhost-WEB-on-localhost.png :width: 60% Web application development environment (1): webserver and client are on the same host computer (localhost). The XAMMP application acts as webserver, and MySQL server is running on ISP host computer. This development option is selected when :phpc:`define('MYSQL_SERVER',HOST_ISP);`, and is the recommended configuration. .. _figure_SQL-WEB-on-localhost: .. figure:: Fig_SQL-WEB-on-localhost.png :width: 60% Web application development environment (2): webserver, MySQL server and client are all on the same host computer (localhost). The XAMMP application acts as webserver. This development option is selected when :phpc:`define('MYSQL_SERVER','LOCAL');`. How to maintain MySQL-server ---------------------------- In most cases MySQL server and webserver are located on the same host. In that case a connection to the MySQL server from the webserver (e.g. website user wants to log on) must be established on the “localhost”. Before the MySQL server can be used a user must be created with a valid password (on a commercial webhost provider the user to be created cannot be the administrator). Be sure that the created user has the proper privileges for using MySQL databases. On most webhost providers there is no total freedom in choosing usernames for the MySQL database server. The server of MySQL can also be managed with phpMyAdmin program. phpMyAdmin application can only be started when logged on the webhost provider. For this reason, using the phpMyAdmin application (to manage the MySQL databases) when it is available on the webhost provider does not require to log on again, even when the usernames of the webserver and the MySQL server are different (also implies that no password is required). .. _sec_L3_MYSQL_DB: Development environment: system location of MySQL database files ---------------------------------------------------------------- For the use of MySQL databases there 2 options: #. Use of MySQL databases on local host for development purpose (see :numref:`figure_SQL-WEB-on-localhost`). It is recommended to use XAMPP on Windows platforms: local host (127.0.0.1): :file:`C:\\xampp\\mysql\\data`. When XAMPP application is running, and thr MySQL server is started, `phpMyAdmin application (1) `_ can be used to maintain the databases. This option is selected when :phpc:`define('MYSQL_SERVER','LOCAL');` in |loginFunctions.php| (see :numref:`listing_mysqlserver`), and :phpc:`'LOCAL'` is just a string. #. Use of MySQL databases on ISP webserver for development purpose (see :numref:`figure_SQL-ISPhost-WEB-on-localhost`). The login credentials for the remote MySQL database server are stored in the file :file:`mysqli_config.ini` (see :numref:`codeblock-mysqli_config`), which is located outside the website document root directory (i.e. file is not direct accessible by the Apache server: e.g. in directory :file:`C:\\dany\\privateWWW\\DreamWeaver\\database_info`), and is read by the PHP function `parse_ini_file() `_. `phpMyAdmin application (2) `_ on the A2Hosting ISP can be used to maintain the databases. This option is selected when :phpc:`define('MYSQL_SERVER',HOST_ISP);` in |loginFunctions.php| (see :numref:`listing_mysqlserver`), and :phpc:`HOST_ISP` is another :phpc:`define`, defined in :file:`/login/database_info.php`. A typical example of file :file:`/login/database_info.php` is given in :numref:`listing_database_info`. .. _listing_mysqlserver: .. literalinclude:: ..\..\..\login\loginFunctions.php :language: php :linenos: :end-before: define("WEBMASTER", "dany"); :caption: Server selection of MYSQL database: on local computer, or ISP (internet service provider), and is implemented in |loginFunctions.php|. .. _listing_database_info: .. literalinclude:: ..\..\..\login\database_info.php :language: php :linenos: :caption: Typical code of :file:`/login/database_info.php`. .. _table_arg_mysqli: .. table:: Values for arguments of PHP function `new mysqli() or mysqli_connect() `_ :widths: 1 1 1 1 :width: 80% +-------------------------------------------------------+--------------------------------+----------------------------+-------------------------------+ | | Local webserver (XAMPP) | ISP webserver (generic) | A2hosting ISP | +=======================================================+================================+============================+===============================+ | PHP define MYSQL_SERVER | :cf:`LOCAL` | :cf:`HOST_ISP` | :cf:`HOST_A2HOSTING` | | |loginFunctions.php| | | | | +-------------------------------------------------------+--------------------------------+----------------------------+-------------------------------+ | host_ip: arg 1 `new mysqli() | :cf:`localhost` | mysql_config.ini: host_ip | :cf:`209.124.66.15` (remark: | | `_| | | this is an dynamic IP address)| +-------------------------------------------------------+--------------------------------+----------------------------+-------------------------------+ | hostname | | mysql_config.ini: hostname | :cf:`nlss4.a2hosting.com` | +-------------------------------------------------------+--------------------------------+----------------------------+-------------------------------+ | username: arg 2 new mysqli() | :cf:`root` | mysql_config.ini: username | :cf:`benoynl_admin` | +-------------------------------------------------------+--------------------------------+----------------------------+-------------------------------+ | password: arg 3 new mysqli() | :cf:`xxxxxx` | mysql_config.ini: password | :cf:`yyyyyyyyy` | +-------------------------------------------------------+--------------------------------+----------------------------+-------------------------------+ | users_db: arg 4 new mysqli() | :cf:`login` | mysql_config.ini: users_db | :cf:`benoynl_website_users` | | | (see :numref:`sec_L4_login_DB`)| | | | (**Name of the database**) | | | | +-------------------------------------------------------+--------------------------------+----------------------------+-------------------------------+ .. _codeblock-mysqli_config: .. code-block:: ini :caption: Example content of file :file:`mysqli_config.ini` for `A2Hosting `_ ISP. [database] host_ip="209.124.66.15" hostname="nlss4.a2hosting.com" username="benoynl_admin" password="************" users_db="benoynl_website_users" Central MySQL database ---------------------- Use of a central MySQL database (located on a remote ISP) has the advantage that less maintenance and updates must be implemented. For example, when the developer’s computer is changed, the MySQL database does not have to be moved to another host (see :numref:`figure_SQL-ISPhost-WEB-on-localhost`). The central MySQL database is installed at the ISP webserver (A2Hosting). In order to approach the MySQL database at the ISP by an external application, the ISP must know the host for security reasons (IP-address, or name) of the computer on which the external application is running: .. table:: Host for remote access to MySQL at ISP (A2Hosting) :widths: 1 2 :width: 50% +------------------------+--------------------------------------+ | Location | Hostname or IP address | +========================+======================================+ | Signify: HTC7 | 130.142.211.% (% represents wildcard)| | | | | | 176.74.235.% | +------------------------+--------------------------------------+ | :strikethrough:`Home` | :strikethrough:`5.132.119.62 | | | (T-Mobile: dynamic IP)` | +------------------------+--------------------------------------+ | Home | 77.162.164.% (143) (KPN: dynamic IP) | +------------------------+--------------------------------------+ Website MySQL databases ----------------------- * Assumption: webserver or internet server (not the local test version), and ISP are on the same server. * Some events on the website will generate e-mails to be sent. The e-mail server for this, does not need to be on the same ISP server, and/or can use different user credentials (i.e. different username and password). E-mail server and its user data are stored in the webserver datatable (see :numref:`sec_L4_ISP_DB`). * Website makes use of MYSQL databases. In general MYSQL server and ISP does not need to be on the same server. For this website it is assumed that MYSQL and ISP are on the same server hardware. * The name of the database on a local server is free to chose (in this case **"login"**: see :numref:`table_arg_mysqli`). The name of the database at an ISP is not always free to chose (as it given by the ISP: see last column in :numref:`table_arg_mysqli`). For the website the database has 3 tables: #. Table **webserver**: e-mail server and user data, #. Table **log**: website event logging (e.g. logging in attempts, page visits, ...) #. Table **members**: website users. The structure of these datatables is given in the next sections. Database functions ^^^^^^^^^^^^^^^^^^ .. table:: Database functions :widths: 3 2 :width: 75% +--------------------------------------------------------+---------------------------------------------+ | Function | Implemented in | +========================================================+=============================================+ | :php:func:`create_database_isp()` | |mysql_create_insert.php| | +--------------------------------------------------------+---------------------------------------------+ | :php:func:`create_database_isp()` | |mysql_create_insert.php| | +--------------------------------------------------------+---------------------------------------------+ | :php:func:`create_tables_members_log` | |mysql_create_insert.php| | +--------------------------------------------------------+---------------------------------------------+ .. _sec_L4_ISP_DB: Table **webserver** ^^^^^^^^^^^^^^^^^^^ The name **webserver** for this datatable might be somewhat confusing. The **webserver** datatable contains login data for the e-mail server. Rows in the table are added by calling :php:`/local/register_isp.php`. #. :cf:`id` (integer type): unique entry number (auto increment), #. :cf:`hostname` (varchar type): webhosting and e-mail servername, #. :cf:`hostadmin` (varchar type): username of host administrator, #. :cf:`hostadmin_password` (varchar type): #. :cf:`hostadmin_email` (varchar type): e-mail address from which system messages are sent to recipient. #. :cf:`hostadmin_alias` (varchar type): name to be used in e-mail header. #. :cf:`iv`: initialization vector for encryption / decryption of the password. Encryption and decryption require additional key, which should never be stored at the server side for security reasons. Encryption can be done on a local host. However, decryption is carried on the webserver so that somehow the key must be known as argument for the decryption function. #. :cf:`SMTP Secure` (varchar type): SMTP security protocol, #. :cf:`port` (integer type): port to be used, #. :cf:`contact_email` (varchar type): send system messages to this contact, #. :cf:`contact_alias` (varchar type): .. _webserver_table_exampple: .. table:: **webserver** Benoy Site :widths: 1 4 4 4 1 4 :column-alignment: center left left left center left :header-alignment: center left left left center left :width: 60% +-----+---------------------+--------------------+-------------------+-------+-----------------+ | Id | hostname | hostadmin | host admin_email | Port | Contact_email | +=====+=====================+====================+===================+=======+=================+ | 4 | nlss4.a2hosting.com | website@benoy.nl | website@benoy.nl | 465 | dany@benoy.nl | +-----+---------------------+--------------------+-------------------+-------+-----------------+ .. _sec_L4_login_DB: Table **log** ^^^^^^^^^^^^^ Created by calling :php:func:`create_tables_members_log`. Rows in the table are added by calling function :php:func:`updateLogDatabaseTable` implemented in file |loginFunctions.php|: #. :cf:`id` (integer type): unique entry number (auto increment), #. :cf:`user_id` (varchar type): #. :cf:`username` (varchar type): name of registered website user when logged on, #. :cf:`email` (varchar type): email address to whom the message will be sent, #. :cf:`message_code`: integer number (see file login/loginFunctions.php), #. :cf:`ip` (varchar type): ip address of login computer, #. :cf:`login_attempt`: date and time, #. :cf:`message` (varchar type): string .. _sec_L4_members_DB: Table **members** ^^^^^^^^^^^^^^^^^ Created by calling :php:func:`create_tables_members_log()`. Rows in the table are added (i.e. new registered user) by calling |register2a.php| (as an AJAX call) #. :cf:`id` (integer type): unique entry number (auto increment), #. :cf:`username` (varchar type): name of registered website user #. :cf:`password` (varchar type): one-way encryption (no decryption possible), #. :cf:`email` (varchar type): #. :cf:`email_password` (varchar type): not yet used, #. :cf:`salt` (char type): random data for one-way encryption, #. :cf:`Group` (enumeration type): Is used to determine the permission level of the user with respect to edit/modify albums. #. :cf:`Timelimit` (tiny integer type): option for later use, #. :cf:`BeginTime` (date type): option for later use, #. :cf:`EndTime` (date type): option for later use. .. _members_table_example: .. table:: **Members** Benoy Site :widths: 1 4 5 3 3 :column-alignment: center left left center center :header-alignment: center left left center center :width: 50% +-----+---------------+-----------------------------+------------+-----------+ | Id | Username | email | Salt | Group | +=====+===============+=============================+============+===========+ | 1 | admin | dany@benoy.nl | 597 | admin | +-----+---------------+-----------------------------+------------+-----------+ | 2 | dany | dany@benoy.nl | 036 | dany | +-----+---------------+-----------------------------+------------+-----------+ | 3 | sophie | sophie@benoy.nl | 461 | familie | +-----+---------------+-----------------------------+------------+-----------+ | 4 | deborah | deborah@benoy.nl | c03 | familie | +-----+---------------+-----------------------------+------------+-----------+ | 5 | veronique | veronique@benoy.nl | 6bc | veronique | +-----+---------------+-----------------------------+------------+-----------+ | 6 | webserver | website@benoy.nl | c84 | familie | +-----+---------------+-----------------------------+------------+-----------+ JavaScript topics ================= Jquery plugins -------------- .. _table_implementation_plugins: .. table:: Implementation locations of Draggable Modal Window plugin. :widths: 2 3 3 :column-alignment: left center center :header-alignment: left center center :width: 80% +-----------------------------+---------------------------------------+----------------------------------------------+ | Plugin | Public | Private | +=============================+=======================================+==============================================+ | Draggable Modal Window | Template: :cf:`/Templates/41184.dwt` | Template: :cf:`/Templates/41184-private.dwt` | +-----------------------------+---------------------------------------+----------------------------------------------+ | VEX Dialog Library | Template: :cf:`/Templates/41184.dwt` | Template: :cf:`/Templates/41184-private.dwt` | +-----------------------------+---------------------------------------+----------------------------------------------+ | Mobilemenu | Template: :cf:`/Templates/41184.dwt` | Template: :cf:`/Templates/41184-private.dwt` | +-----------------------------+---------------------------------------+----------------------------------------------+ | Spinner activity indicator | Template: :cf:`/Templates/41184.dwt` | Template: :cf:`/Templates/41184-private.dwt` | +-----------------------------+---------------------------------------+----------------------------------------------+ | Superfish menu | Template: :cf:`/Templates/41184.dwt` | Template: :cf:`/Templates/41184-private.dwt` | +-----------------------------+---------------------------------------+----------------------------------------------+ | Idle timeout | NA | Template: :cf:`/Templates/41184-private.dwt` | +-----------------------------+---------------------------------------+----------------------------------------------+ Jquery versions ^^^^^^^^^^^^^^^ Plugin: Draggable Modal Window Google Style ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ **Website**: * http://www.stupidcodes.com/draggable-modal-window-google-style * http://www.cssscript.com/google-style-draggable-modal-window-with-pure-javascript/ **Plugin script**: * :file:`/js/modal/draggabilly.pkgd.js` (version v1.1.2), or * :file:`/js/modal/draggabilly.pkgd.min.js`, and * :file:`/js/modal/modal.js` Called in: see :numref:`table_implementation_plugins`. Plugin: Full Width Tab ^^^^^^^^^^^^^^^^^^^^^^ **Website**: * http://tympanus.net/Blueprints/FullWidthTabs/ * http://tympanus.net/codrops/2014/03/21/responsive-full-width-tabs/ Plugin is used for generating media processing and status window, and tab overview of photo albums Media processing windows as shown in :numref:`figure_DialogMsgBox_MediaProcessStatus` |r_arrow| :numref:`figure_DialogMsgBox_MediaProcessStatus_tab4` are using “Responsive Full Width Tabs”. **Plugin script**: * :file:`/js/cbpFWTabs.js` (version v1.0.0) Called in: see :numref:`table_implementation_FWT`. .. _table_implementation_FWT: .. table:: Implementation locations of Draggable Modal Window plugin. :widths: 1 1 1 :column-alignment: left left left :header-alignment: left left left :width: 70% +-----------------------------+-------------------------------------+---------------------------+ | Public | Private | Comment | +=============================+=====================================+===========================+ | :phpc:`dany-fiets.php` | :phpc:`dany-fiets-private.php` | Processing status window | +-----------------------------+-------------------------------------+---------------------------+ | :phpc:`familie.php` | :phpc:`familie-private.php` | Album overview | +-----------------------------+-------------------------------------+---------------------------+ | :phpc:`familie-vakantie.php`| :phpc:`familie-vakantie-private.php`| Processing status window | +-----------------------------+-------------------------------------+---------------------------+ Plugin: Lean modal ^^^^^^^^^^^^^^^^^^ .. _sec_L4_CH1_VEX_lib: Plugin: Highly Configurable JS Modal & Dialog Box Library – Vex ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ **Website**: * http://github.hubspot.com/vex **Plugin script**: * :file:`/vex/js/vex.combined.min.js` (version ??) Called in: see :numref:`table_implementation_plugins`. **Dialog types**: #. Alert (display a message to the user), #. Confirm (user has 2 options), #. Prompt (user can provide input), #. Open (full design control). Plugin: Idle timeout ^^^^^^^^^^^^^^^^^^^^ **Website**: * https://www.npmjs.com/package/jquery-idleTimeout-plus. **Plugin script**: * :file:`/js/timeout/jquery-idleTimeout-plus.min.js` (version ??) Called in: see :numref:`table_implementation_plugins`. **Main setting parameters**: * idleTimeLimit [seconds]: default 1200, * warnTimeLimit [seconds]: default 180, * logoutCallback: logout_timeout(), * redirectCallback: logout_timeout(), Plugin: Spinner activity indicator ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ **Website**: * https://spin.js.org/#v2.3.2 **Plugin script**: * :file:`/js/spninner/spin.min.js` Called in: see :numref:`table_implementation_plugins`. **Main setting parameters**: .. table:: Spinner settings :widths: 2 1 3 :column-alignment: left center left :header-alignment: left center left :width: 60% +----------------------------+-----------+----------------------------------------------------+ | Option | Value | Description | +============================+===========+====================================================+ | :cf:`lines` | 11 | The number of lines to draw | +----------------------------+-----------+----------------------------------------------------+ | :cf:`length` | 15 | The length of each line | +----------------------------+-----------+----------------------------------------------------+ | :cf:`width` | 10 | The line thickness. | +----------------------------+-----------+----------------------------------------------------+ | :cf:`radius` | 30 | The radius of the inner circle. | +----------------------------+-----------+----------------------------------------------------+ | :cf:`corners` | 1 | Corner roundness (0..1). | +----------------------------+-----------+----------------------------------------------------+ | :cf:`rotate` | 0 | The rotation offset. | +----------------------------+-----------+----------------------------------------------------+ | :cf:`direction` | 1 | 1: clockwise, -1: counterclockwise. | +----------------------------+-----------+----------------------------------------------------+ | :cf:`color` | '#000' | #rgb or #rrggbb. | +----------------------------+-----------+----------------------------------------------------+ | :cf:`speed` | 0.6 | Rounds per second. | +----------------------------+-----------+----------------------------------------------------+ | :cf:`trail` | 60 | Afterglow percentage. | +----------------------------+-----------+----------------------------------------------------+ | :cf:`shadow` | false | Whether to render a shadow. | +----------------------------+-----------+----------------------------------------------------+ | :cf:`hwaccel` | false | Whether to use hardware acceleration. | +----------------------------+-----------+----------------------------------------------------+ | :cf:`className` | 'spinner' | The CSS class to assign to the spinner. | +----------------------------+-----------+----------------------------------------------------+ | :cf:`zIndex` | 2e7 | The z-index (defaults to 2000000000). | +----------------------------+-----------+----------------------------------------------------+ Superfish is a jQuery plugin that adds usability enhancements to multi-level drop-down menus. Event data as argument of callback function ------------------------------------------- Event is an object with different properties and methods defined in **JavaScript** and **JQuery**. (References: https://www.w3schools.com/jsreF/obj_event.asp, and https://www.tutorialrepublic.com/jquery-reference/jquery-event-object.php) .. _table_event_properties: .. table:: Event properties in JavaScript and JQuery :widths: 2 1 1 4 :column-alignment: left center center left :header-alignment: left center center left :width: 80% :class: lasttable +---------------------------------+------------+--------+------------------------------------------------+ | Property | Javascript | JQuery | Description | +=================================+============+========+================================================+ | bubbles | YES | NO | Returns whether or not a specific event is a | | | | | bubbling event. | +---------------------------------+------------+--------+------------------------------------------------+ | cancelBubble | YES | NO | Sets or returns whether the event should | | | | | propagate up the hierarchy or not. | +---------------------------------+------------+--------+------------------------------------------------+ | cancelable | YES | NO | Returns whether or not an event can have its | | | | | default action prevented. | +---------------------------------+------------+--------+------------------------------------------------+ | composed | YES | NO | Returns whether the event is composed or not. | +---------------------------------+------------+--------+------------------------------------------------+ | createEvent() | YES | NO | Creates a new event. | +---------------------------------+------------+--------+------------------------------------------------+ | composedPath() | YES | NO | Returns the event's path. | +---------------------------------+------------+--------+------------------------------------------------+ | currentTarget | YES | YES | Returns the element whose event listeners | | | | | triggered the event. | +---------------------------------+------------+--------+------------------------------------------------+ | data | NO | YES | An optional DOM element within the event | | | | | bubbling phase. | +---------------------------------+------------+--------+------------------------------------------------+ | defaultPrevented | YES | NO | Returns whether or not the preventDefault() | | | | | method was called for the event. | +---------------------------------+------------+--------+------------------------------------------------+ | delegateTarget | NO | YES | Returns the elementwhere the currently-called | | | | | JQuery event handler was attached. | +---------------------------------+------------+--------+------------------------------------------------+ | eventPhase | YES | NO | Returns which phase of the event flow is | | | | | currently being evaluated. | +---------------------------------+------------+--------+------------------------------------------------+ | isDefaultPrevented() | NO | YES | Returns whether event.preventDefault() was | | | | | ever called on this event object. | +---------------------------------+------------+--------+------------------------------------------------+ | isImmediatePropagationStopped() | NO | YES | Returns whether stopImmediatePropagation() was | | | | | ever called on this event object. | +---------------------------------+------------+--------+------------------------------------------------+ | isPropagationStopped() | NO | YES | Returns whether event.StopPropagation() was | | | | | ever called on this event object. | +---------------------------------+------------+--------+------------------------------------------------+ | isTrusted | YES | NO | Returns whether or not an event is trusted. | +---------------------------------+------------+--------+------------------------------------------------+ | metaKey | NO | YES | Indicates whether the WIndows key or Command | | | | | key (on Mac ekyboard) was pressed when the | | | | | event fired. | +---------------------------------+------------+--------+------------------------------------------------+ | namespace | NO | YES | Returns the namespace specified when the event | | | | | was triggered. | +---------------------------------+------------+--------+------------------------------------------------+ | pageX | NO | YES | Returns the mouse position relative to the | | | | | left edge of the document. | +---------------------------------+------------+--------+------------------------------------------------+ | pageY | NO | YES | Returns the mouse position relative to the | | | | | top edge of the document. | +---------------------------------+------------+--------+------------------------------------------------+ | preventDefault() | YES | YES | Cancels the event if it is cancelable, meaning | | | | | that the default action that belongs to the | | | | | event will not occur. | +---------------------------------+------------+--------+------------------------------------------------+ | relatedTarget | NO | YES | Returns the other DOM element involved in the | | | | | event, if any. | +---------------------------------+------------+--------+------------------------------------------------+ | result | NO | YES | The last or pe\revious value returned by an | | | | | event handler that was triggered by this event.| +---------------------------------+------------+--------+------------------------------------------------+ | stopImmediatePropagation() | YES | YES | Prevents other listeners of the same event from| | | | | being called. | +---------------------------------+------------+--------+------------------------------------------------+ | stopPropagation() | YES | YES | Prevents further propagation of an event during| | | | | event flow. | +---------------------------------+------------+--------+------------------------------------------------+ | target | YES | YES | Returns the element that triggered the event. | +---------------------------------+------------+--------+------------------------------------------------+ | timeStamp | YES | YES | Returns the time (in milliseconds relative to | | | | | the epoch) at which the event was created. | +---------------------------------+------------+--------+------------------------------------------------+ | type | YES | YES | Returns the name of the event. | +---------------------------------+------------+--------+------------------------------------------------+ | which | NO | YES | Indicates the specific key or button that was | | | | | pressed for key or mouse events. | +---------------------------------+------------+--------+------------------------------------------------+ Userdata can be stored in the **data** property of the **Event** object. This is used in (mouse)click event to pass specific webpage (i.e. parameters) info to a callback function. To pass parameters to user callback function Web (client-side) API interfaces for JavaScript ----------------------------------------------- DOM: HTML interface, Window Object ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ DOM stands for Document Object Model, and is a programming interface for JavaScript to HTML. It main purpose is to manipulate web documents. Therefor an important object is the **Window Object**. **Reference website**: https://www.tutorialride.com/javascript/javascript-dom-window-object.htm * Window object is a top-level object in Client-Side JavaScript. * Window object represents the browser's window. * It represents an open window in a browser. * It supports all browsers. * The document object is a property of the window object. So, typing window.document.write is same as document.write. * All global variables are properties and functions are methods of the window object. The Window Object Properties are given https://www.w3schools.com/jsref/obj_window.asp. One of the useful properties being used is **sessionStorage**. The sessionStorage object stores data (user defined key/value pairs) for only one session (the data is deleted when the browser tab is closed). It is used with keys **currentPage**, and **previousPage** (defined as integers meaning that the each website page must have a unique integer ID number), and can be considered as simpler implementation of the **history** object property. The keys **currentPage**, and **previousPage** are set in initialization function :js:func:`initSessionStorage` implemented in :js:mod:`js\\myjs\\public_private.js`. FETCH: get data from web server ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The **Fetch API** is a simple interface for fetching resources. Fetch allows us to make network request and handle responses easier than our old friend **XMLHttpRequest(XHR)**. One of the main differences is that Fetch API uses **Promises**, which provides a way to avoid callbacks hell and boilerplate heavy code that **XMLHttpRequest(XHR)** provides. The **fetch()** method takes one mandatory argument, the path to the resource you want to fetch. It returns a **Promise** that resolves to the Response to that request, whether it is successful or not. More detailed information on the fetch API can be found on https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API. PROMISE: tracking of asynchronous operations ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A Promise is an object representing the eventual completion or failure of an **asynchronous** operation. More detailed information on promises can be found `here `_. The asynchronous process can be either on the web server-side, or on the client-side. If it is on the server-side the promise will need to make a **XMLHttpRequest** request. If it is on the client-side, the asynchronous process can be started immediately (locally). Constants --------- .. table:: Value of constants used in VEX dialog boxes :widths: 3 1 3 2 :column-alignment: left center left left :header-alignment: left center left left :width: 70% :class: lasttable +----------------------------+-------+---------------------------------------------+------------------------------+ | Constant | Value | Used in function | File | +============================+=======+=============================================+==============================+ | LOGOUT | 0 | :js:func:`user_menu_dialogbox()` | |dlgboxes_private.js| | +----------------------------+-------+---------------------------------------------+------------------------------+ | WIJZIG_WACHTWOORD | 1 | :js:func:`user_menu_dialogbox()` | |dlgboxes_private.js| | +----------------------------+-------+---------------------------------------------+------------------------------+ | LOGIN | 2 | :js:func:`adminuser_dialogbox_pub()` | |dlgboxes_public.js| | +----------------------------+-------+---------------------------------------------+------------------------------+ | RNG | 3 | :js:func:`admininistrator_tools_dialogbox()`| |dlgboxes_private.js| | +----------------------------+-------+---------------------------------------------+------------------------------+ | USER_ADMIN | 4 | :js:func:`user_menu_dialogbox()` | |dlgboxes_private.js| | +----------------------------+-------+---------------------------------------------+------------------------------+ | FILEMANAGER | 5 | :js:func:`user_menu_dialogbox()` | |dlgboxes_private.js| | +----------------------------+-------+---------------------------------------------+------------------------------+ | MEDIA_UPDATE_PROGRESS_TEST | 6 | :js:func:`user_menu_dialogbox()` | |dlgboxes_private.js| | +----------------------------+-------+---------------------------------------------+------------------------------+ | STATUS_WINDOW | 7 | | | | | | * :js:func:`adminuser_dialogbox()` | * |dlgboxes_private.js| | | | | * :js:func:`adminuser_dialogbox_pub()` | * |dlgboxes_public.js| | +----------------------------+-------+---------------------------------------------+------------------------------+ | PHP_VERSION | 8 | :js:func:`admininistrator_tools_dialogbox()`| |dlgboxes_private.js| | +----------------------------+-------+---------------------------------------------+------------------------------+ | LOGOFF | 9 | :js:func:`adminuser_dialogbox()` | |dlgboxes_private.js| | +----------------------------+-------+---------------------------------------------+------------------------------+ | SESSION_INFO | 10 | :js:func:`admininistrator_tools_dialogbox()`| |dlgboxes_private.js| | +----------------------------+-------+---------------------------------------------+------------------------------+ | WEBLOG_VISITS | 11 | :js:func:`admininistrator_tools_dialogbox()`| |dlgboxes_private.js| | +----------------------------+-------+---------------------------------------------+------------------------------+ | MYSQL_BACKUP | 12 | :js:func:`admininistrator_tools_dialogbox()`| |dlgboxes_private.js| | +----------------------------+-------+---------------------------------------------+------------------------------+ | LOCALHOST_DEF | 13 | :js:func:`system_info_dialogbox()` | |dlgboxes_private.js| | +----------------------------+-------+---------------------------------------------+------------------------------+ | SYSTEM_INFO | 14 | :js:func:`user_menu_dialogbox()` | |dlgboxes_private.js| | +----------------------------+-------+---------------------------------------------+------------------------------+ | SYSTEM_INFO | 15 | :js:func:`system_info_dialogbox()` | |dlgboxes_private.js| | +----------------------------+-------+---------------------------------------------+------------------------------+ | LOCAL_DB | 16 | :js:func:`mysql_backup_dialogbox()` | |dlgboxes_private.js| | +----------------------------+-------+---------------------------------------------+------------------------------+ | ISP_DB | 17 | :js:func:`mysql_backup_dialogbox()` | |dlgboxes_private.js| | +----------------------------+-------+---------------------------------------------+------------------------------+ HTML 5 ====== Form validation --------------- * HTML 5 helps to validate to validate user input to be given in a form dialog. See `client side validation `_ * HTML 5 built-in form validation (i.e. no Javascript is needed) using the following attributes: * :html:`required`, * :html:`minlength` and :html:`maxlength`, * :html:`type`, * :html:`pattern`: regular expression * Browsers mark the input box different when the condition for the :html:`required` attribute is not fulfilled: see e.g. https://www.the-art-of-web.com/html/html5-form-validation/. Tooltips are different for different type of inputs (see :numref:`table_browser_differences_tooltips`). .. _table_browser_differences_tooltips: .. table:: Used HTML 5 form attribute settings, and tooltips of different browsers. All input types have the :html:`required` attribute. :align: center :header-alignment: center center center center center :column-alignment: left left left left left :width: 90% :class: lasttable +-------------------------+-----------------------+-------------------------------+-------------------------------------+-------------------------------------------------+ | Input type | Dialog window | Tooltip Firefox | Tooltip Chrome | Tooltip Edge | +=========================+=======================+===============================+=====================================+=================================================+ | username | | Please fill out this field | Vul dit veld in | Please fill out this field | | | * login | | | | | * minlength=3 | * Wachtwoord vergeten | | | | | * pattern="^\s*\S+\s*$" | | | | | +-------------------------+-----------------------+-------------------------------+-------------------------------------+-------------------------------------------------+ | password | Login | Please fill out this field | Vul dit veld in | Please fill out this field | +-------------------------+-----------------------+-------------------------------+-------------------------------------+-------------------------------------------------+ | email | Wachtwoord vergeten | Please enter an email address | Gebruik een '*' in het email adres | Please include an '*' in the email address ... | +-------------------------+-----------------------+-------------------------------+-------------------------------------+-------------------------------------------------+ Media files ----------- Browser compatibility ^^^^^^^^^^^^^^^^^^^^^ Reference: https://developer.mozilla.org/en-US/docs/HTML/Supported_media_formats. We will make use of the new :html:`