Category Archives: PHP

PHP substr_replace

Want to mask part of a string – say a API key or the first 12 digits of a credit card?

Here is a PHP function for doing the job easily

substr_replace(API_USER],"xxxxxxxxxxxx",6,12); //this will replace 12 characters starting from 6th position

substr_replace(API_PASS,"xxxxxxxxxxxxxxxxxxxxxxxxxxxxx",6,28); //this will replace 28 characters starting from 6th position of the string

 

Some WordPress Tricks

Redirect some or users to a particular URL after logging in

function login_redirect( $redirect_to, $request, $user ) 
{ 
   return ( is_array( $user->roles ) && in_array( 'sln_staff', $user->roles ) ) ? "https://mydevfactory.com/~appfactory/salonBooking/wp-admin/admin.php?page=salon" : admin_url(); /* here sln_staff is the admin group for which a redirect will happen after logging in */
}

add_filter( 'login_redirect', 'login_redirect', 10, 3 );

 

Remove the Black Admin bar that appears on top of site when the user is logged in

function remove_admin_bar() 
{ 
   show_admin_bar(false);
}
add_action('after_setup_theme', 'remove_admin_bar');

Remove the WordPress update notice on top of the Dashboard

function hide_update_notice_to_all_but_admin_users() 
{ 
   if (!current_user_can('update_core')) { 
     remove_action( 'admin_notices', 'update_nag', 3 ); 
   } 
   $user = wp_get_current_user(); 
   /*echo ($user['roles'][0]); 
   if(in_array( 'sln_staff', $user->roles )) 
     echo "SLN_STAFF"; 
   else 
     echo "WHOEVER";*/
}

add_action( 'admin_head', 'hide_update_notice_to_all_but_admin_users', 1 );

 

Remove the Dashboard items using the Screen Options and then remove the Screen Options and Help tab

function remove_help_tabs($old_help, $screen_id, $screen)
{ 
   $screen->remove_help_tabs(); 
   return $old_help;
}

add_filter( 'contextual_help', 'remove_help_tabs', 999, 3 );
add_filter('screen_options_show_screen', '__return_false');

 

Amazon AWS SDK Passing Credentials

As per the the sample codes the AWS API access key and secret is to be stored in the a file called credentials under a folder named .aws 

The location of that .aws folder can be set in the code through this config statement

putenv('HOME=/path/that/you/want/to/set');

But I am more comfortable in passing the credentials through my code so that I can make things more flexible and need not worry about write permissions.

To pass the credentials through code the first thing needed is to remove or not to use the config statement

'profile' => 'default'

The credentials can then be passed like below

$xxxxxxClient = new xxxxxxClient([
   'version' => "<CLIENT VERSION>", /* can be set to 'latest' */
   'region' => "<REGION>",
   'credentials' => array(
     'key' => "<API USER>",
     'secret' => "<API PASS>"
    )
]);

 

Installing Amazon SDK on ISPConfig systems

  1. First install Composer and PHP for the jailed user. This article has the steps
  2. composer require aws/aws-sdk-php  — as the jailed user
  3. There might be an error –
    fopen(/usr/share/php/Composer/Autoload/../../../doc/composer/copyright): failed to open stream: No such file or directory
  4. You can copy the file using the root login
    1. mkdir -p /var/www/clients/client1/web1/usr/share/doc/composer
    2. cp /usr/share/doc/composer/copyright  /var/www/clients/client1/web1/usr/share/doc/composer/
    3. chown web1:client1 /var/www/clients/client1/web1/usr/share/doc/composer/copyright

CKEditor – WYSIWYG Editor for Web

This is a quick guide about integrating CKEditor

Download CKEditor from here – https://ckeditor.com/ckeditor-4/download/ I downloaded the full version.
Call the scripts in your code

<script src="ckeditor_full/ckeditor.js"></script>
...
...
<textarea required id="content" name="content"><?php echo strlen($content) ? $content : "" ?></textarea><br/> 
<script>
 var editor = CKEDITOR.replace('content');
 //CKEDITOR.instances['content'].setData("");
 CKFinder.setupCKEditor(editor); //see below - this is for the CKFinder and can be omitted if file uploading is not needed
</script>
...
...
...
<script> 
//validation if needed
 if(document.getElementById("content").value.length == 0)
 {
   CKEDITOR.instances[0].updateElement(); //Updates the <textarea> element that was replaced by the editor with the current data available in the editor. This is to ensure that it is updated before doing the check alert("Provide the mail body"); return false; } </script>

The above will replace the plain textarea with the CKEditor.

The number of toolbars and tools depends on the version of CKEditor (full or basic etc).

For a customizing the toolbar

CKEDITOR.editorConfig = function( config ) {
           // Define changes to default configuration here.
          // For complete reference see:
          // http://docs.ckeditor.com/#!/api/CKEDITOR.config

         // The toolbar groups arrangement, optimized for two toolbar
          rows.config.toolbarGroups = [


{ name: 'clipboard', groups: [ 'clipboard', 'undo' ] },
{ name: 'editing', groups: [ 'find', 'selection', 'spellchecker' ] },
{ name: 'links' },
{ name: 'insert' },
{ name: 'forms' },
{ name: 'tools' },
{ name: 'document', groups: [ 'mode', 'document', 'doctools' ] },
{ name: 'others' },
'/',
{ name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] },
{ name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ] },
{ name: 'styles' },
{ name: 'colors' },
{ name: 'about' }
];

 

For making the file upload and drag drop uploads working with album view

Download the CKFinder from here  https://ckeditor.com/ckfinder/download/  I used the PHP version
Call the script in the code

<script src="ckfinder/ckfinder.js"></script>

Open the config.php file (under root of the ckfinder folder) and modify the following highlighted lines with suitable values

$config['backends'][] = array(
   'name' => 'default',
   'adapter' => 'local',
    'baseUrl' => 'https://xxxxxxxxxx.com/projectname/ckfinder/userfiles/', /* note - I have used an URL but folder names and paths can be used also*/
    // 'root' => '', // Can be used to explicitly set the CKFinder user files directory.
    'chmodFiles' => 0644, //this by default was 777 I changed that to 644
    'chmodFolders' => 0755,
   'filesystemEncoding' => 'UTF-8',
);

Enable the PHP adapter (we used the default PHP adapter that comes with the CKFinder)

$config['authentication'] = function () {
   return true;  // by default this is false
};

Add the required plugins and enable them in the config.js of the CKEditor

CKEDITOR.editorConfig = function( config ) {
      // Define changes to default configuration here. For example:
     // config.language = 'fr';
    // config.uiColor = '#AADC6E';

    config.extraPlugins = 'notification';  //https://ckeditor.com/cke4/addon/notification -- required by Notification Aggregator plugin
    config.extraPlugins = 'notificationaggregator'; //https://ckeditor.com/cke4/addon/notificationaggregator  -- -- required by Upload

    config.extraPlugins = 'filetools';   //https://ckeditor.com/cke4/addon/filetools -- required by Upload
    config.extraPlugins = 'uploadwidget'; //https://ckeditor.com/cke4/addon/uploadwidget -- required by uploadimage
    config.extraPlugins = 'uploadimage'; //
};

The PHP connector comes with the CKFinder

Here are the files used above (latest versions as of time of writing)

filetools_4.11.2

notificationaggregator_4.11.2

notification_4.11.2

ckfinder_php_3.4.5

ckeditor_4.11.2_full

uploadwidget_4.11.2

uploadimage_4.11.2

Web 3D experiments with ThreeJS

Here is an experiment where a fixed background (or texture) has been used behind an interact-able 3D model. The model was created using Blender. From Blender (or any other 3D software) export the model as FBX file.

The code formatting is getting horribly misaligned when pasted here. So here is the whole folder. Run the webgl_loader_fbx2.php. Though I have included files.js, but it not needed for this experiment.

three.js-experiments — Download sample app from here.

Here is a sample 3D box created using Blender (fbx format).

PHP code for Amazon SNS Auto Subscription Confirmation (HTTPS)

Amazon Simple Notification Service or SNS is a messaging service which be used to send notifications by SMS, Email, Push notification or to a URL endpoint.

For a quick on setting up Amazon SNS see this article Amazon SNS setup for HTTPS and Email

Code for auto confirmation of subscriptions

<?php
$json_write_to_text = file_get_contents("php://input"); //read the raw data 
$json_write_to_text = json_decode($json_write_to_text, TRUE, 512, JSON_OBJECT_AS_ARRAY);

if($json_write_to_text['Type'] == SubscriptionConfirmation)
{
 $curl = curl_init();

 curl_setopt_array($curl, array(
  CURLOPT_URL => $json_write_to_text['SubscribeURL'],
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => $header,
 ));

 $response = curl_exec($curl);
 $err = curl_error($curl);

 curl_close($curl);
}

file_put_contents("response.txt",print_r($json_write_to_text,true)); // this is just for dumping the raw data and can be omitted 
?>

 

 

Amazon SNS setup for HTTPS and Email

Login to AWS Console

Goto Simple Notification Service

Create a Topic

Add a Subscription – the easy and safe way to do this is by clicking the ARN of the Topic (in the topic listing page ) and going to the Topic details page.

Topic Details
Subscription Protocols

Choose your subscription protocol (in simpler words in which way you want the notifications to be delivered)

Subscription Protocols

Amazon SNS will do a verification. The method depends on the protocol chosen. For example for emails it will send an email with a verification link, for HTTP or HTTPS it will call the endpoint with some data like below. On opening or hitting the SubscribeURL the verification will be complete.

Array
(
[Type] => SubscriptionConfirmation
[MessageId] => eeexxxea-xxxx-xxxx-xxxx-c15xxxx81361
[Token] => 2336412f3xxxxxxxxxxxxxxxxxxxxxxxxee34aadbb4eb9c926c288f8ca1xxxxxxxxxxxxcbe27c6835edd47bd28d0cf1d0cb9b4xxxxxxxx1003b95c6bc1231db657b1bb465a7d98c73a8d79faddb473a1a109c45654a1db1f11xxxxxxxxxxxxxxxxxxxf74dae61acfbe2f508901390b2cd6
[TopicArn] => arn:aws:sns:us-east-x:0xxxxxxxxxx9:xxx-bounce
[Message] => You have chosen to subscribe to the topic arn:aws:sns:us-east-x:0xxxxxxxxxx9:xxx-bounce.
To confirm the subscription, visit the SubscribeURL included in this message.
[SubscribeURL] => https://sns.us-east-1.amazonaws.com/?Action=ConfirmSubscription&TopicArn=arn:aws:sns:us-east-x:0xxxxxxxxxx9:xxx-bounce&Token=2336412f3xxxxxxxxxxxxxxxxxxxxxxxxee34aadbb4eb9c926c288f8ca1xxxxxxxxxxxxcbe27c6835edd47bd28d0cf1d0cb9b4xxxxxxxx1003b95c6bc1231db657b1bb465a7d98c73a8d79faddb473a1a109c45654a1db1f11xxxxxxxxxxxxxxxxxxxf74dae61acfbe2f508901390b2cd6
[Timestamp] => 2019-01-09T14:53:31.247Z
[SignatureVersion] => 1
[Signature] => euyT80G1NujWgQMWfltxxxxxxxxxxxxxxxiDqeicbE1FH5dwdBnAA7UY84zHf0fsJCd/xxxxxxxxxxxxxxxxxxxxxxxxx/rxx/t/wKxxxxxx/LKg2QwcjGPdnIh4xp6rNA4PKihOjMiPfTZYH4kQV+h+4zqFsQT1UL+ixlM+xBZqZY3zUV1lrHKz+SfIkPJxxxxxxxxxxIB2FN0O2leokHJYRlUqxxxxxxkMzlbsMg4ChDW8+hcJ14hNEz5kpM5T0Fqljt2CmqkF1BQ68ViTgFV7yYpcSTbejo0DuZAUxxxxxxxxxx5y340TcfTWWq+3hKSTtB9aTclgDchvLDYKNqg==
[SigningCertURL] => https://sns.us-east-x.amazonaws.com/SimpleNotificationService-ac56xxxxxxxxxxxxxxxxxxxx8aa1d9b.pem
)

Once the verification is complete the Subscription ID will show an ARN. See The Topic Details picture.

Sample PHP code for auto-verification of SNS Subscriptions for HTTP/HTTPS protocols PHP code for Amazon SNS Auto Subscription Confirmation (HTTPS)

 

 

 

ISPConfig PHP-FPM Session Problem

The problem I was facing – session variables not getting passed from page to page. On page1.php I set some session variables and then on going to page2.php all I was getting was Array() !  The problem drove me crazy as everything settings and permissions were fine.

I have ISPConfig 3 on Ubuntu 18.04 and PHP 7.2.

Session path, folder ownership, folder permission, cookie path everything was fine. On checking the Session folder found that the session file is getting created properly and the session variables also got saved in files properly. Also had session_start() at the beginning of every page. And there was no error or warnings. But when going to next page – nothing in session!

Then on further analysis found the issue is all about the PHPSESSID cookie being set by ISPConfig control panel. After logging out of ISPConfig panel when I opened my pages the SESSION variables got passed fine.

I spent a whole day trying to find issues with the setup or server configuration. Hope this saves someone else’s time.

 

 

 

 

How to Setup MQTT Server on a Windows 10 Desktop

  1. Download the Win32 installer from the below link (I couldn’t successfully installed the CygWin version)
    https://mosquitto.org/download/
  2. Once downloaded, install the package
  3. During the start of the installation process it will show links from where some dependencies will have to be downloaded
  4. Copy/Open the links
  5. Once the installation finishes go to the websites opened in the previous step
  6. Download the OpenSSL installer and the pthreadVC2.dll file
  7. Install the OpenSSL
  8. Copy the pthreadVC2.dll file to the directory where mosquitto executable has been installed. Normally C:\Program Files (x86)\mosquitto
  9. Open folder where OpenSSL got installed (normally C:\OpenSSL\) and open the lib folder (normally C:\OpenSSL\lib)
  10. Copy ssleay32.lib and libeay32.lib into the folder where mosquitto executable has been installed.
  11. Please note – while copying the files Windows might ask for giving Admin permission. Go ahead.
  12. At this point Mosquitto should be ready to run————————————————————–
  13. Now testing mosquitto
  14. Open a Command Prompt
  15. Goto the folder where mosquitto is installed
  16. Give command mosquitto.exe -v -c mosquitto.conf
  17. The server should now start listening on port 1883
  18. Now open another Command Prompt
  19. Give the command mosquitto_sub -h localhost -t channel1/data1
  20. Open a third Command Prompt and give the command mosquitto_pub -h localhost -t channel1/data1 -m “test data”
  21. In the command prompt where we used mosquitto_sub (step 18 and 19) will show the message “test data” sent from the third command prompt.
  22. Reaching this point means mosquitto is working fine———————————————-
  23. To secure the transmission we can username and password authentication
  24. Open a command prompt with Admin privileges
  25. Goto the folder where Mosquitto is installed
  26. Create a password file (for the first time only) using the command mosquitto_passwd.exe -c passfile.txt username
  27. It will ask for password. Give the password and confirm the password
  28. After this point further users can be added using the below command mosquitto_passwd.exe -b passfile.txt username password
    Please note – this time we supplied the password also along with the username
  29. Now edit the config file (mosquitto.conf normally located in C:\Program Files (x86)\mosquitto) to enforce only authenticated data transfers
  30. Uncomment allow_anonymous and set it false
  31. Uncomment password_file and put the password file name after it. It will look like password_file passfile.txt
  32. Now onwards all sub and pub requests will have to be with username and password of a user whose details exists in the password file. Examples below
    mosquitto_pub -h localhost -t channel1/data1 -m "test data" -u john -P johnpass 
    
    mosquitto_sub -h localhost -t channel1/data1 -u jane -P janepass
  33. Access control can be done using a acl file or using mosquitto-auth-plug (https://github.com/jpmens/mosquitto-auth-plug)
  34. There should be a aclfile.example inside your mqtt directory. If not then also no problem we will shortly see the contents of the file below.
  35. Create a file with any name. Here we will use aclFile.txt
  36. In the mosquitto.conf file uncomment acl_file and put the name of your acl file after that. It will look something like acl_file aclFile.txt
  37. Example content of aclFile.txt as below
     # user jane given full permission to channel1/data1 and only read permission to channel1/data2
    user jane
    topic channel1/data1
    topic read channel1/data2
    
    # user jane given full permission to both data1 and data2 channel
    user john
    topic channel1/#

Please put in your suggestions in comment.

MQTT on Windows  — Download link of Word File containing the above steps. WordPress had made some filenames missing. So uploaded the original word doc.