About PHP Dynamic Qr code

PHP Dynamic Qr code is a script that allows the generation and saving of dynamic and static QR codes. It has clean, responsive and user-friendly design. It is Based on AdminLte the "Best open source admin dashboard & control panel theme. Built on top of Bootstrap" and Core PHP Admin Panel, a simple Admin Pannel written in core PHP that contains an implementation of general features you might need in your website admin panel like: record management (CRUD), secure authentication, pagination, filters.

N.B. A careful reading of this documentation is recommended to fully understand how the script works.

What is a dynamic qr code

A Dynamic QR code has a modifiable destination URL.
A Short URL is placed into the QR code which then transparently re-directs the user to the intended destination. The destination of a dynamic QR code can be changed at any time and as often as you want – even if your marketing material has already been printed. This will save reprinting costs, effort and enable you to respond to any changes in the campaign as quickly as possible.

What is a static qr code

A Static QR code has a fixed destination URL.
The information encoded in static QR codes are fixed. The destination/data is stored directly in the QR Code graphic (hence QR codes are also getting larger and form a more complex pattern if there is more data to store). Therefore, the stored destination/data cannot be changed. Any typo in an already printed QR code cannot be changed, as with any other printed material. Through this script you can create 13 different types of static qr code.

Installation

Follow these steps to install the script:

  1. Extract the zip archive to your server
  2. Open the /install/ folder in the browser
  3. Check system requirements. If one of these extensions is not enabled, you must enable it from your server settings. If all requirements are provided, click Next.

  4. Check folder permissions
  5. If a folder doesn't have read and write permissions you need to change the settings on your server. If all requirements are provided, click Next.

  6. Enter your database credentials. Click next.
  7. Finish
  8. The installation is finished and you can access the control panel.

Frontend Files Structure


a) CSS Files
  • dist/css/adminlte.min.css Contains general css codes for admin panel
  • dist/css/alt folder Contains additional styles files
  • plugins/fontawesome-free/css/all.min.css Contains css of fontawesome
  • plugins/bootstrap-colorpicker/css/bootstrap-colorpicker.min.css Contains css of color picker input data
  • plugins/daterangepicker/daterangepicker.css Contains css of daterange input data
  • plugins/overlayScrollbars/css/OverlayScrollbars.css Contains css of the scrollbar relating to template customization (top right)

b) JS Files
  • dist/js/adminlte.js Contains general js codes for admin panel
  • dist/js/custom.js Contains custom js code for front-end
  • build/ folder Contains general dashboard script codes

c) Plugins used in application
  • Bootstrap The world’s most popular front-end open source toolkit
  • Bootstrap colorpicker Bootstrap Colorpicker is a modular color picker plugin for Bootstrap 4
  • Chart JS Simple yet flexible JavaScript charting for designers & developers
  • Date Range Picker A JavaScript component for choosing date ranges, dates and times
  • Fontawesome The world's most popular and easiest to use icon set just got an upgrade
  • jQuery jQuery is a JavaScript library that greatly reduces the amount of code that you must write
  • jQueryUI jQuery UI is a curated set of user interface interactions, effects, widgets, and themes built on top of the jQuery JavaScript Library
  • jQuery Validation This jQuery plugin makes simple clientside form validation easy
  • Moment JS Moment will still create a moment global, which is useful to plugins and other
  • Overlay Scrollbars A JavaScript scrollbar plugin which hides native scrollbars and provides custom styleable overlay scrollbars

Backend Files Structure

  • config
    • config.php
  • forms
    • static
      • bitcoin.php
      • bookmark.php
      • country-code.html
      • email.php
      • event.php
      • location.php
      • paypal.php
      • phone.php
      • skype.php
      • sms.php
      • text.php
      • vcard.php
      • whatsapp.php
      • wifi.php
    • dynamic_table.php
    • static_table.php
    • users_table.php
    • add_dynamic_form.php
    • add_static_form.php
    • edit_dynamic_form.php
    • edit_static_form.php
    • users_form.php
    • filters.php
    • logo.php
    • qrcode_options.php
  • helpers
    • helpers.php
  • includes
    • head.php
    • footer.php
    • navbar.php
    • sidebar.php
    • search_order.php
    • auth_validate.php
    • flash_messages.php
  • lib
    • MysqliDb
      • MysqliDb.php
    • Dynamic_Qrcode
      • Dynamic_Qrcode.php
    • Static_Qrcode
      • Static_Qrcode.php
    • Users
      • Users.php
    • vCard
      • vCard.php
    • ICS
      • ICS.php
  • saved_qrcode
  • index.php
  • login.php
  • logout.php
  • authenticate.php
  • dynamic_qrcodes.php
  • static_qrcodes.php
  • admin_users.php
  • add_dynamic.php
  • add_static.php
  • add_admin.php
  • edit_dynamic.php
  • edit_static.php
  • edit_admin.php
  • delete_dynamic.php
  • delete_static.php
  • delete_users.php

a) Open source libraries used
  • MysqliDb Simple MySQLi wrapper and object mapper with prepared statements
  • vCard Qr code This class allows to easily generate a simple QR code using vCard 4.0
  • PHP to ICS A convenient script to generate iCalendar (.ics) files on the fly in PHP

Database Structure


a) dynamic_qrcodes
  • `id` -- int -- primary key -- auto increment
  • `filename` -- varchar
  • `format` -- varchar
  • `identifier` -- longtext
  • `link` -- varchar
  • `qrcode` -- varchar
  • `scan` -- varchar
  • `state` -- varchar -- default: enable
  • `created_by` -- int
  • `created-at` -- timestamp

b) static_qrcodes
  • `id` -- int -- primary key -- auto increment
  • `filename` -- varchar
  • `format` -- varchar
  • `type` -- varchar
  • `content` -- mediumtext
  • `qrcode` -- varchar
  • `state` -- varchar
  • `state` -- varchar -- default: enable
  • `created_by` -- int
  • `created-at` -- timestamp

b) admin_accounts
  • `id` -- int -- primary key -- auto increment
  • `user_name` -- varchar
  • `password` -- varchar
  • `series_id` -- varchar
  • `remember_token`-- mediumtext
  • `expires` -- datetime
  • `admin_type` -- varchar

In this script we use the open source MysqliDb library. It is a very large library, however this script only needs the simplest functions.
The configuration file for the database (and more) is located in /config/config.php and it is included in all php files of this script. To interact with the database, therefore, it will be necessary to call the function: getDbInstance().

MysqliDb class methods used:
query() : A method to perform select query, return array. Contains the returned rows from the query, LINE 646
getValue() : A convenient SELECT COLUMN function to get a single column value from one row, return array of values, LINE 787
insert() : Insert method to add new row, LINE 818
update() : Update query that need first where() method, LINE 905
where() : This method allows you to specify multiple (method chaining optional) AND WHERE statements for SQL queries, LINE 969
orWhere() : This method allows you to specify multiple (method chaining optional) OR WHERE statements for SQL queries, LINE 1012
orderBy() : This method allows you to specify multiple (method chaining optional) ORDER BY statements for SQL queries, LINE 1229
getLastError() : Method returns mysql error, LINE 2079
paginate() : Pagination wrapper to get(), LINE 2401


Script Structure

  1. General
  2. The optimization work has produced a script consisting of modules (php pages) with a similar macro-structure to each other. All pages include the config.php file which in turn includes the helpers.php file and the MysqliDb class and the auth_validation.php file which takes care of verifying on each page that the user is logged in (read authentication types).

      Explanation of the config.php file
                                  
      /*This file is generated after the script installation wizard and contains some constants used throughout the script as well as database credentials.*/
      
      //Get current page:
      
      define('CURRENT_PAGE', basename($_SERVER['REQUEST_URI']));
      
      
      //You can change the folder where the qr code will be saved:
      
      define('PATH', './saved_qrcode/');    
      
      
      //The directory includes the full path needed by the server (Apache). You can test by printing it.
      
      define('DIRECTORY', BASE_PATH.'/saved_qrcode/');
      
      
      //You can change the page name for the redirect and the search parameter (the default is "id"):
      
      define('READ_PATH', $_SERVER['HTTP_HOST'].'/read.php?id=');     
      
      
      require_once BASE_PATH . '/lib/MysqliDb/MysqliDb.php';
      require_once BASE_PATH . '/helpers/helpers.php';
      
      define('DB_HOST', "%HOST%");
      define('DB_USER', "%USER%");
      define('DB_PASSWORD', "%PASSWORD%");
      define('DB_NAME', "%DB_NAME%");
      
      
      /**
       * Get instance of DB object
       */
      function getDbInstance() {
      	return new MysqliDb(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
      }
                                  
                              

    As for the HTML structure, all pages start by including the head.php page which contains the entire head tag, the navbar.php page, the sidebar.php page. There is a header with the page title and then the different main content for each page. Finally, each page includes the footer.php file with the required js scripts; some pages have additional js scripts needed As specified at the beginning, the frontend part of this script is done with AdminLTE (Bootstrap). We therefore recommend reading the official documentation to fully understand the HTML structure.

  3. Qr code and Admin users
  4. The dashboard page has a separate structure, while the dynamic qr codes, static qr codes and users sections have a very similar structure to each other.

    List all page (the same for all 3 sections)
    ├─ *page_name*.php
    ├─ ├─ includes/flash_messages.php
    ├─ ├─ includes/filters.php
    ├─ ├─ forms/*name*_table.php

    The following shows which files are included in the management pages (add, edit, delete) of the 3 sections:

    Dynamic qr codes section
    ├─ add_dynamic.php
    ├─ ├─ forms/add_dynamic_form.php
    ├─ edit_dynamic.php
    ├─ ├─ forms/edit_dynamic_form.php
    ├─ delete_dynamic.php

    Static qr codes section
    ├─ add_static.php
    ├─ ├─ forms/add_static_form.php
    ├─ ├─ ├─ forms/static/*type*.php   example: text.php
    ├─ ├─ ├─ ├─ forms/qrcode_options.php
    ├─ edit_static.php
    ├─ ├─ forms/edit_static_form.php
    ├─ delete_static.php

    Admin section
    ├─ add_admin.php
    ├─ ├─ forms/users_form.php
    ├─ edit_admin.php
    ├─ ├─ forms/users_form.php
    ├─ delete_user.php

This script is designed as OOP as possible. Therefore, all QR code management operations are performed using classes and methods. There are 3 classes for 3 sections (dynamic, static, users). All 3 have the same macrostructure. Below there is the explanation of only the two classes (dynamic, static). Within the explanations for the classes I do not write the entire code but I limit myself only to indicate a clear reference.

N.B. Some functions are not mentioned or explained in detail because there are adequate comments inside the class file.

How authentication works

There are two levels of authentication: admin and superadmin. The difference between the two is that the admin level cannot add or delete qr code. It is enabled to consult and modify the QR code already created. At installation time there is only one default superadmin user that it is recommended to change.

This script adopts a "simple" but secure authentication method also with the aid of COOKIES to memorize the user's access and two pages for login and logout are included, moreover, most of the operations take place through external functions located in the helpers.php file.

Dynamic Qr code class


a) private functions
  • collect()
      Dynamic_Qrcodes.php - collect()
                                  
      /*It is a function called by add() and by edit() which allows you to initially store common data for both insertion and modification. 
      For this class these data are:                                                                                                              */
      
      $data_to_db['filename'];
      $data_to_db['created_at'];
      $data_to_db['link'];
      
      
      //the function returns an array with the results which will be expanded later by the add() and edit() functions with additional specific data:
      
      return $data_to_db;
                                  
                              
  • setOptions()
  • addLogo()
  • failure()
  • success()
  • info()


b) public functions
  • setOrderingValues()
  • add()
      Dynamic_Qrcodes.php - add()
                                  
      //We collect all the data necessary for the database and to build the qr code in this array:
      
      $data_to_db
      
      
      //We collect all the additional options for the qr code through the setOptions() method in this array:
      
      $options
      
      
      /*If in the folder where we save the qr code (constant "DIRECTORY") there is no file with the same name (and format), 
      we proceed with the creation:                                                                                                               */
      
      if(!file_exists(...))
      
      
      //We take the generated qr code and we create the name of the complete file to be inserted into the saved qr code folder:
      
      $content = file_get_contents(...);
      $filename = DIRECTORY.$data_to_db['filename'].'.'.$data_to_db['format'];
      file_put_contents($filename, $content);
      
      
      //We insert in the database all the fields collected in input:
      
      $db->insert('dynamic_qrcodes', $data_to_db);
                                  
                              
  • edit()
      Dynamic_Qrcodes.php - edit()
                                  
      //Through $_GET we recover the id of the qr code and the name of the current file:
      
      $dynamic_id = htmlspecialchars($_GET['dynamic_id'], ENT_QUOTES, 'UTF-8');          
      $old_filename = htmlspecialchars($_GET['filename'], ENT_QUOTES, 'UTF-8'); 
      
      
      //We recover from the database the image format of the qr code with id taken from input:
      
      $format
      
      
      /*To update the database we take the essential data with the collect() method and the "state" field as input. 
      We also update the "qrcode" field with the name of the file taken from input but with the same format:                                      */
      
      $data_to_db
      
      
      /*If in the folder where we save the qr code (constant "DIRECTORY") there is no file with the new name or old name (and format), 
      we proceed with the creation:                                                                                                               */
      
      if(!file_exists(...))
      
      
      //We find the row corresponding to the id taken in input with the where() method and update the row with the new data with the update() method:
      
      $db->where('id', $dynamic_id);
      $db->update('dynamic_qrcodes', $data_to_db);
      
      
      //Let's rename the qr code file previously created with the new name via PHP function rename():
      
      rename($old, $new);
                                  
                              
  • cancel()
      Dynamic_Qrcodes.php - cancel()
                                  
      //We verify that the logged in user is of type "super" otherwise we print an error message:
      
      if($_SESSION['admin_type']!='super')
          $this->failure('You don\'t have permission to perform this action');
      
      
      //We recover from the database the image format of the qr code with id taken from input:
      
      $format
      
      
      //We find the row corresponding to the id taken in input with the where() method and update the row with the new data with the delete() method:
      
      $db->where('id', $dynamic_id);
      $db->delete('dynamic_qrcodes');
      
      
      //We delete from the folder the qr code that we want to delete through the php unlink() function:
      
      unlink($file);
                                  
                              

Static Qr code class


a) private functions
  • collect()
      Static_Qrcodes.php - collect()
                                  
      /*The function has the same purpose as the analogue already seen previously. 
      However,a "link" is not stored in this class, but the "type" of the qr code is assigned in addition to the "filename" and "created_at" fields: 
      */
      
      $data_to_db['filename'];
      $data_to_db['created_at'];
      
      
      /*The type is assigned in the creation phase and can no longer be modified, in fact a check is made on $ _GET['type'] 
      to verify that the function has been called by add() in order to "capture" the type.
      If it is not very clear, review the section of the entry concerning static QR codes                                                         */
      
      if($_GET['type'] != NULL)
          $data_to_db['type'] = htmlspecialchars($_GET['type']);
      
                                  
                              
  • setOptions()
  • addLogo()
  • failure()
  • success()
  • info()
  • requiredFieldsError()
  • add()
      Static_Qrcodes.php - add()
                                  
      /*The function is very similar to add() for dynamic qr code. 
      It naturally differs in the data type of the qr code, which must be encoded to be used in a query part of a URL:                            */
      
      $sData = urlencode($sData);
      
      
      /*We collect all the data necessary for the database and to build the qr code in this array 
      (in this class we also add the "content" that has been stored in the qr code):                                                              */
      
      $data_to_db;
      $data_to_db['content'] = $sContent;
      
      
      //The rest is all the same as the add() seen above...
                                  
                              


b) public functions
  • setOrderingValues()
    • Methods for different types of static qr code:
    • textQrcode()
        Example - textQrcode()
                                    
        public function textQrcode($text)
            {
                if($text != NULL){
                    $this->sData = $text;
                    $this->sContent = '<strong>Text:</strong> '.$text;
                    $this->add($this->sData, $this->sContent);
                }
                else
                    $this->requiredFieldsError();
            }
            
            
        /*Each function has as parameter the data to be inserted in the qr code, some of which are mandatory depending on the type.
        
        A check is made on the mandatory data as if they were "NULL" it would mean that the user has not filled in the required field; 
        in this case it ends by printing a standard error message.
        
        Otherwise, proceed to assign to the variable (declared private) sData what will be stored in the qr code 
        (possibly accompanied by standard strings for the type of qr code requested).
        
        The sContent variable is assigned the content to be stored in the database, already in HTML format ready for printing in the table.
        
        The function add() is called (in this class it is declared private) which receives the data for the qr code 
        and the content to be stored in the database                                                                                    */
                                    
                                
    • emailQrcode()
    • phoneQrcode()
    • smsQrcode()
    • whatsappQrcode()
    • skypeQrcode()
    • locationQrcode()
    • eventQrcode()
        Explanation of eventQrcode()
                                    
        /*It is possible to create an "event" qr code which, if scanned, adds the desired event to the default calendar. 
        This is possible thanks to the .ics calendar format.
        We use a very convenient external library that automatically generates a single string to be stored in the qr code:             */
        
        $ics = new ICS(array(
                        'location' => $location,
                        'description' => $description,
                        'dtstart' => $start,
                        'dtend' => $end,
                        'summary' => $title,
                        'url' => $url
                    ));
                    
        $this->sData = $ics->to_string();
        
        /*After checking the mandatory data, the ICS class receives the event data through the array and 
        exploits the concatenation between strings through the to_string() function to generate the unique string to be stored.         */
                                    
                                
    • vcardQrcode()
        Explanation of vcardQrcode()
                                    
        //Operation similar to eventQrcode() through the aid of an external library to generate the vCard 4.0 string to be stored.
        
        $vcard = new vCard;
            $vcard->name($fullname);
            $vcard->nickName($nickname); 
            $vcard->email($email); 
            $vcard->url($website); 
            $vcard->cellPhone($phone); 
            $vcard->homePhone($home_phone); 
            $vcard->workPhone($work_phone); 
            $vcard->organization($company); 
            $vcard->role($role); 
            $vcard->categories($categories); 
            $vcard->note($note); 
            $vcard->photo($photo); 
            $vcard->address($address, $city, $postcode, $state); 
            $vcard->create();
                    
        $this->sData = $vcard->get();
        
        
        /*After checking the mandatory data, for each field a special function is called which concatenates all the information 
        in a single string. It is retrieved through the get() function.                                                                 */
                                    
                                
    • bookmarkQrcode()
    • wifiQrcode()
    • paypalQrcode()
    • bitcoinQrcode()
  • edit() same operation of the analogous function for dynamic qr code
  • cancel() same operation of the analogous function for dynamic qr code

Dashboard

The dashboard is the main page of the script. In this section there is a counter of the total number of qr code in the database, and in particular also the number of dynamic and static ones. There is also a counter regarding the number of scans of the dynamic qr code.
The script offers 2 examples of dynamic charts created with chart.js The first shows a weekly report of the number of qr codes created (dynamic and static), the second graph offers an overview of the number of scans of dynamic qr codes.

  1. Report of qr code
  2. Dashboard
                                
    //The values are determined by counting the number of lines through the getValue library function:
    
    $db->getValue ("table_name", "count(*)");
    
    
    //A custom query is available for the value of the scans that sum all the values of the scan column:
    
    $db->query("SELECT sum(scan) FROM dynamic_qrcodes");
                                
                            
  3. Chart
  4. Chart code - PHP
                                
    //For the first chart I select the "created_at" column (of the dynamic and static qr code tables) with a value between the current date and 7 days less:
    
    $db->query("select `created_at`, `scan` from "table_name" where `created_at` > curdate()-7;");
    
    
    /*I also select the "scan" column with the same criteria because I will need it for the second graph.
    I scan the entire array and through a switch having as expression the substring of type YYYY-MM-DD of the results extracted from the database.
    N.B. In our database we store the "created_at" field also with the date and time because it is useful for sorting the qr code:                          */
    
    foreach ($result as $row) {
        switch (substr($row['created_at'],0,10)){
        case 
        ...
        }
    }    
                                
                            
    Chart code - JS
                                
    /*For the complete functioning of the chart.js library visit the link in the documentation.
    The js codes of the graphs are found in the <footer> tag. We make a graph dynamic by modifying the "labels" attribute and the "data" attribute 
    with values obtained from database.                                                                                                                     */
    
    //In particular for "labels" we print 7 dates in the format YYYY-MM-DD.
    
    
    <?php echo date("Y-m-d",mktime(0,0,0,date('m'),date('d'),date('Y'))); ?>
    <?php echo date("Y-m-d",mktime(0,0,0,date('m'),date('d') - 1,date('Y'))); ?>
    <?php echo date("Y-m-d",mktime(0,0,0,date('m'),date('d') - 2,date('Y'))); ?>
    ...
    
    
    //Then for the "date" attribute we print the variables obtained from the previous calculations, for example:
    
    <?php echo $dynamic_sixday ?>           
    <?php echo $static_today ?>             
    <?php echo $scan_twoday ?>
                                
                            

List All

The structure of the code for the listing process is the same for all types of QR code. Below there is an example for dynamic qr codes.
There is a main page, in this case dynamic_qrcodes.php, which contains the code to retrieve the data necessary for the table and an external page called search_order.php which implements functions for searching and sorting the qr code.
The HTML code includes: the flash_message.php file for managing the various messages to be printed, the filters.php file for managing the search and sorting filters and the dynamic_table.php file with the code that creates the entire table.

    dynamic_qrcodes.php
                                
    //We retrieve the database instance and define which columns to extract from the database for the table we need:
    
    $db = getDbInstance();
    $select = array('id', 'filename', 'identifier', 'link', 'qrcode', 'scan', 'created_at', 'updated_at');
    
    
    /*We define the parameters with which it is possible to sort the qr codes in the table.
    N.B. The parameters for ascending and descending sorting are always included separately in addition to those chosen by us.                              */
    
    $search_fields = array('filename', 'identifier', 'link');
    require_once BASE_PATH . '/includes/search_order.php';
    
    
    /*We use the variable $page to keep track of the page where we are. 
    By default the value is "1" and we need it because we can set an element limit for each page with a special library function:                           */
    
    $page = filter_input(INPUT_GET, 'page', FILTER_SANITIZE_FULL_SPECIAL_CHARS) ?? 1;
    $db->pageLimit = 15;
    
    
    //We build the pagination with the elements extracted from the database through a convenient library function:
    
    $rows = $db->arraybuilder()->paginate('dynamic_qrcodes', $page, $select);
    $total_pages = $db->totalPages;
                                
                            
    dynamic_table.php
                                
    //We define the dimensions for each column. Example:
    <thead>
        <tr>
            <th width="5%">ID</th>
            <th width="15%">Filename</th>
            <th width="18%">Unique redirect identifier</th>
            ...
        </tr>
    </thead>
    
    
    //We print the entire array of results extracted from the database in the respective columns. Example:
    
    <tbody>
        <?php foreach ($rows as $row): ?>
        <tr>
            <td><?php echo $row['id']; ?></td>
            <td><?php echo htmlspecialchars($row['filename']); ?></td>
            <td><?php echo htmlspecialchars($row['identifier']); ?></td>
            ...
            <td>
    /*The script includes 3 operations: modification, cancellation, download of the qr code. All 3 have their own button but the modification operation 
    refers to an external link, the cancellation is managed through a "modal fade" within the same page, while the HTML "download" attribute 
    is simply used for the download:                                                                                                                    */
    
    <!-- EDIT -->
        <a href="edit_dynamic.php?filename=<?php echo $row['filename']; ?>&dynamic_id=<?php echo $row['id']; ?>&operation=edit" class="btn btn-primary"><i class="fas fa-edit"></i></a>
        
    <!-- DELETE -->
        <a href="#" class="btn btn-danger delete_btn" data-toggle="modal" data-target="#confirm-delete-<?php echo $row['id']; ?>"><i class="fas fa-trash"></i></a>
                        
    <!-- DOWNLOAD -->
        <a href="<?php echo PATH.htmlspecialchars($row['qrcode']); ?>" class="btn btn-primary" download><i class="fa fa-download"></i></a>
        
            </td>
        </tr>
    /*For cancellation, the modal uses an external page (in this case delete_dynamic.php) using a form within the main page 
    that includes two hidden input fields: filename, del_id. Before confirming the cancellation, a different message is shown depending on the type of QR code.
    */
    
    //We conclude the end of printing the elements and the table body:
    
    <?php endforeach; ?>
    </tbody>
                                
                            

How does the insertion of a dynamic qr code work?

The main page dedicated to the insertion is add_dynamic.php the form HTML-tag is also declared on this page, however the input fields are separated in another page called add_dynamic_form.php for a matter of code reusability

    add_dynamic.php
                                
    //Let's create an instance of the class for the dynamic Qr code we discussed earlier:
    
    require_once BASE_PATH . '/lib/Dynamic_Qrcode/Dynamic_Qrcode.php';
    $dynamic_qrcode = new Dynamic_Qrcode();
    
    
    //We verify that the form has been sent with the POST method and we call the add() function shown above:
    
    if ($_SERVER['REQUEST_METHOD'] === 'POST')
        $dynamic_qrcode->add();
    
                                
                            
    add_dynamic_form.php
                                
    /*The input fields are recognized by the class through the "name" attribute. For example, the underlying input creates the "colorpicker" tool 
    whose data will be sent and processed by the class with the name (attribute) "foreground" and the chosen value "value":                                 */
    
    <input type="text" class="form-control" id="foreground" name="foreground" value="#000000">
    
    
    //Similarly, there are some types of selection inputs with different options. The input is sent with a "name" and with a "value":
    
    <select name="level" class="form-control">
        <option value="L">L - Smallest</option>
        <option value="M">M - Medium</option>
        <option value="Q">Q - High</option>
        <option value="H">H - Best</option>
    </select>
    
                                
                            

How does the insertion of a static qr code work?

The main page dedicated to the insertion is add_static.php Unlike the previous creation page, the one for static qr codes does not provide a single form HTML-tag but each type of static qr code has its own form. For the input fields there is a secondary page called add_static_form.php which contains the menu of the various types of qr code that can be created and for each card (for each type) another file is included with the individual input fields, for example text.php

    add_static.php
                                
    //Let's create an instance of the class for the static Qr code we discussed earlier:
    
    require_once BASE_PATH . '/lib/Static_Qrcode/Static_Qrcode.php';
    $static_qrcode = new Static_Qrcode();
    
    
    /*We verify that the form has been sent with the POST method and with a control switch we examine the type of qr code that you want to create 
    through $ _GET ['type'] present in the link after sending the corresponding form. Each type corresponds to a different class method 
    that sends as parameters the input data of the form with the POST method. Example with the type "text":                                                 */
    
    if ($_SERVER['REQUEST_METHOD'] === 'POST'){
        switch($_GET['type']){
            case 'text':    $static_qrcode->textQrcode($_POST['text']); break;
            ...
        }
    }
    
                                
                            
    add_static_form.php
                                
    /*Within this page there is a menu divided into tabs in which each contains a different form depending on the type of static qr code to create.
    Example with "text" type:                                                                                                                               */
    
    <ul class="nav nav-tabs" role="tablist">
        <li class="nav-item">
            <a class="nav-link active" data-toggle="pill" href="#text" role="tab" aria-controls="custom-tabs-four-home" aria-selected="true">Text 
                <i class="fas fa-align-left"></i>
            </a>
        </li>
        ...
    </ul>
    
    <div class="tab-content" >
        <div class="tab-pane fade show active" id="text" role="tabpanel" aria-labelledby="custom-tabs-four-home-tab">
            <?php include BASE_PATH . '/forms/static/text.php'; ?>      
        </div>
        ...
    </div>
                    
                            
    text.php
                                
    /*Each page relating to a type of qr code has the same structure. In particular, it is characterized by a form which once sent provides the input data 
    to the main creation page with the type inside the link (?type=), the options to customize the qr code and the individual input fields different from 
    type to type. Example for "text" type:                                                                                                                  */
    
    <form class="form" action="./add_static.php?type=text" method="post" id="static_form" enctype="multipart/form-data">
        <?php include BASE_PATH.'/forms/qrcode_options.php'; ?>
    <!-- Input forms -->
    </form>
                    
                            

How does the modification of a qr code work?

The modification process is essentially the same for both types of QR code.
For dynamic qr code is possible to change: the file name, the url and is possible to enable or disable the redirect when the qr code is scanned. It is not possible to change the image format of the QR code as well as its unique identifier.
For static qr codes is only possible to change the file name, since by definition a static qr code cannot be changed in its content. The image format of the qr code cannot be changed.
Below there is an example of the modification process for dynamic qr code, which I repeat is the same for both types.
The main page dedicated to the edit is edit_dynamic.php the form HTML-tag is also declared on this page, however the input fields are separated in another page called edit_dynamic_form.php for a matter of code reusability.

    edit_dynamic.php
                                
    //Let's create an instance of the class for the Dynamic Qr code we discussed earlier
    
    require_once BASE_PATH . '/lib/Dynamic_Qrcode/Dynamic_Qrcode.php';
    $dynamic_qrcode = new Dynamic_Qrcode();
    
    
    /*We retrieve from the link the id of the qr code and the requested operation (edit). I chose to add this additional parameter 
    because from the qr code table it is possible to add different operations for each one.                                                                 */
    
    $dynamic_id = htmlspecialchars($_GET['dynamic_id'], ENT_QUOTES, 'UTF-8');
    $operation = htmlspecialchars($_GET['operation'], ENT_QUOTES, 'UTF-8');
    
    
    //We verify that the form has been sent with the POST method and we call the edit() function shown above:
    
    if ($_SERVER['REQUEST_METHOD'] === 'POST') 
        $dynamic_qrcode->edit();
        
    //If the requested operation is edit, we retrieve the information needed to fill in the edit form through the id of the qr code:
    
    if ($edit){
        $db->where('id', $dynamic_id);
        $dynamic_qrcode = $db->getOne('dynamic_qrcodes');
    }
                                
                            
    edit_dynamic_form.php
                                
    /*The input fields are similar throughout the script. What changes is the declaration of the "value" attribute. 
    In fact, the value is retrieved from the database only if the edit operation has been chosen:                                                           */
    
    <input type="text" name="identifier" value="<?php echo htmlspecialchars($edit ? $dynamic_qrcode['identifier'] : '', ENT_QUOTES, 'UTF-8'); ?>">
                    
                            

How does the deletion of a qr code work?

The deletion process is essentially the same for both types of QR code. It is a very simple process, here is an example for static qr codes.
There is a single delete_dynamic.php delete page which is reached through a unique link for each element in the qr code table.

    delete_dynamic.php
                                
    //Let's create an instance of the class for the Static Qr code we discussed earlier:
    
    require_once BASE_PATH . '/lib/Static_Qrcode/Static_Qrcode.php';
    $static_qrcode = new Static_Qrcode();
    
    
    /*We verify that the form has been sent with the POST method and we call the cancel() function shown above. 
    To this function we send as parameters the id of the qr code and the name of the file                                                                   */
    
    if ($_SERVER['REQUEST_METHOD'] === 'POST')
        $static_qrcode->cancel($_POST['del_id'], $_POST['filename']);
                                
                            

What happens when i scan a dynamic qr code?

The dynamic QR code reading process is quite simple. There is a single read.php page that does all the operations. By default this page is located outside the main directory, however with your modifications it is possible to change its location. Instead, it is easier to change the name of this page, taking care to change the name also in the classes where the qr code is generated

    read.php
                                
    //Each link is generated in the form /read.php?id=xxxxx, so we retrieve the present id:
    
    $get_id = htmlspecialchars($_GET['id'], ENT_QUOTES, 'UTF-8');
    
    
    //We retrieve the database instance and select the link associated with the unique id as well as its status (enabled or disabled):
    
    $db = getDbInstance();
    $state = $db->query("SELECT state FROM dynamic_qrcodes WHERE identifier='$get_id'");
    $link = $db->query("SELECT link FROM dynamic_qrcodes WHERE identifier='$get_id'");
    
    
    //We increase the scan field since the qr code has just been scanned:
    
    $update = $db->query("UPDATE dynamic_qrcodes SET scan=scan+1 WHERE identifier='$get_id'");
    
    
    /*If the qr code is enabled we proceed with a normal HTML redirect towards the associated link; otherwise we print a simple message
    informing the user that the link is disabled:                                                                                                           */
    
    if($state[0]['state'] == 'enable'){
            echo '<meta http-equiv="refresh" content="0; URL='.$link[0]['link'].'" />';         
            echo 'Loading...';                                                                  
    }
    else
        echo 'Disabled link';
        
        
    //N.B. Any custom pages to show during the redirect are not included in this script.
                                
                            

EXTRA

My script is in constant development and I hope to expand it from time to time with more and more useful features, so stay tuned for the updates.
With the first version, in the classes that realize the 2 types of qr code, an additional method not mentioned in the above documentation called addLogo() is included. To add this functionality you need to delete the comment characters inside the class and add the input fields to the forms for the user to upload the logo. However, this feature is not recommended as it can cause different QR code scanning errors depending on the scanner applications.

Updates

  • Version 1.0 – September, 2020 (Initial release)

Support

Please don't forget to rate my script on GitHub.

Thank You,

Giandonato Inverso