Senin, 10 September 2018

Code Igniter, retrieving return value from view

You might need someday retrieving a return value from view. Well, I am glad that I finally knew it that it is possible.

So this is how we can do it.

The common usage of function to load a view is like this.

$this->load->view("myPage", $arrayOfData);


But if your view should return a value, then do this

$returnVal = $this->load->view("myPage", $arrayOfData, TRUE);

Yup, this function has a third parameter. If you set it as TRUE, than it will return the value, otherwise it will return CI Object.

Code Igniter ERROR syntax error, unexpected 'use' (T_USE)

Some of you might face this problem, when you try to integrate github library to your Project and you are using CodeIgniter.

The main problem is

You cannot put 'use' inside a function.

But you might have to use it inside your model. To solve it, I put the php file using the 'use' inside the 'views' directory and load it as a views.

In this example I am using the Github's shamir secret sharing library that is developed by Oliver Mueller and Stefan Gehrig.

model.php
<?php 

public function shamirSecretSharing()
{
       $data['message'] = 'this is a secret';
       return $this->load->views('shamir/compute');
}


?>

And here is my compute.php located in "..\application\views\shamir\compute.php".

compute.php
<?php 

require_once APPPATH. 'views/shamir/autoload.php';

use TQ\Shamir\Secret;

$shares = Secret::share($message, 3, 3);

return $shares;

?>

I'm not going to explain the function of the library. What I want to show is how I use the Library inside my model. If you ask me, what APPPATH mean. You can read it here.

required, required_once, include Problem in Codeigniter

I had a problem integrating a library downloaded from github in codeigniter. One of the problem is the "required_once" function.

I'm sure there are many ways to solve this problem. I have two ways to share in this post.

Problem:

In every library downloaded from github, we need to call the autoload.php file at the start using "required_once". In some chases, required_once will be used almost in every php file. It is an old way to integrate github library in your code.

First Way:
Load it as a view.
For example, you need to include the autoload.php file.
Put the whole directory of the library inside the directory of 'views' and do this in the controller

controller.php
<?php

public function myFunc()
{
    $this->load->view('yourLib/autoload');
    $this->load->view('yourPageFile');
}
?>

Or you can do that inside the model as well'

aModel.php
<?php

public function modelFunc()
{
    $var=$this->load->view('yourLib/autoload','',true);
    
    your code ....
}
?>

Take a look at the load views. There are 3 parameters of the view function. The first parameter is the file of the page that you want to show, second parameter is for the variables that will be used in the page and the third parameter is set to TRUE. It will tell the CI that you want to return a value from view. If you don't set it to TRUE, it will return an CI-Object.

Second Way:
Use APPPATH macro. APPPATH is a macro referring your application Path.

If I do this
include_once APPATH."views/myLib/autoload.php";

that will give you  
include_once "c:\xampp\htdocs\myApp\application\views\myLib\autoload.php";

I hope this can help you somehow

Minggu, 02 September 2018

Sending Email with PHP

I got a request to create a web Application with a requirement sending a Warning via E-mail. First thing I did was googling, "sending Email with PHP", "how to send Email with PHP", ect. Thanks to many website and its author that give me a lot of information how to do that. I do really thank you guys for every information that you provide on your website.

I found so many tutorial with the complete library and the example how to use it. Unfortunately, many don't work. BUT...I blame my self, I'm the one who doesn't know how to use it. Then, I stopped for a minute and try to figure it out, how is the logical steps for a web server using PHP to send an E-mail. let me straight to the point, we cannot send an E-mail just using the PHP. Maybe I'm wrong at this point, but if we really could do it, I'm sure that we should make some changes in our web server's configuration.

So, what can we do then? We create a Mail Client using PHP. 
  1. Check the mail client manual setting in your web host. If you are using cpanel, check in Email Accounts --> Connect Devices --> Set up Mail Client
  2. Download PHPMailer here. Thanks to Marcus Bointon that provides us this library.
  3. Create the autoload.php, read it here how to do it. 
Before I continue to the PHP code, lets create the autoload.php for the PHPMailer library. Here is how the autoload.php looks like:

<?php
/**
 * An example of a project-specific implementation.
 *
 * After registering this autoload function with SPL, the following line
 * would cause the function to attempt to load the \Foo\Bar\Baz\Qux class
 * from /path/to/project/src/Baz/Qux.php:
 *
 *      new \Foo\Bar\Baz\Qux;
 *
 * @param string $class The fully-qualified class name.
 * @return void
 */
spl_autoload_register(function ($class) {

    // project-specific namespace prefix
    $prefix = 'PHPMailer\PHPMailer';

    // base directory for the namespace prefix
    $base_dir = __DIR__ . '/src/';

    // does the class use the namespace prefix?
    $len = strlen($prefix);
    if (strncmp($prefix, $class, $len) !== 0) {
        // no, move to the next registered autoloader
        return;
    }

    // get the relative class name
    $relative_class = substr($class, $len);

    // replace the namespace prefix with the base directory, replace namespace
    // separators with directory separators in the relative class name, append
    // with .php
    $file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';

    // if the file exists, require it
    if (file_exists($file)) {
        require $file;
    }
});

Put that autoload.php inside PHPMailer directory.

I am using Code Igniter, I put the PHPMailer inside the view. So I load it as a view to use the library.

This is how my function in controller looks like:

public function testMail()
{
    $this->load->view('PHPMailer/autoload');
    $this->load->view('sendMail');
}

and here is the sendMail.php


<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;


$mail = new PHPMailer(true);                              // Passing `true` enables exceptions
try {
    //Server settings
    $mail->SMTPDebug = 2;                                 // Enable verbose debug output
    $mail->isSMTP();                                      // Set mailer to use SMTP
    $mail->Host = 'mail.yourHost.com';                  // Specify main and backup SMTP servers
    $mail->SMTPAuth = true;                               // Enable SMTP authentication
    $mail->Username = 'user@yourHost.com';                 // SMTP username
    $mail->Password = 'password';                           // SMTP password
    $mail->SMTPSecure = 'tls';                            // Enable TLS encryption, `ssl` also accepted
    $mail->Port = 26;                                    // TCP port to connect to

    //Recipients
    $mail->setFrom('user@yourHost.com', 'User's Name');
    $mail->addAddress('recepient@test.com', 'Recipient Name');     // Add a recipient
    //$mail->addAddress('recepient@test.com');               // Name is optional
    $mail->addReplyTo('user@yourHost.com', 'User's Name');
    //$mail->addCC('cc@example.com');
   // $mail->addBCC('bcc@example.com');

    //Attachments
   // $mail->addAttachment('/var/tmp/file.tar.gz');         // Add attachments
    //$mail->addAttachment('/tmp/image.jpg', 'new.jpg');    // Optional name

    //Content
    $mail->isHTML(true);                                  // Set email format to HTML
    $mail->Subject = 'Subject';
    $mail->Body    = 'write something here';
    //$mail->AltBody = 'This is the body in plain text for non-HTML mail clients';

    $mail->send();
    echo 'Message has been sent';
} catch (Exception $e) {
    echo 'Message could not be sent. Mailer Error: ', $mail->ErrorInfo;
}

?>

You can check your SMTP Configuration on your cpanel. That is already everything.

GitHub autoload.php

Some of you may need autoload.php after downloading a PHP library from gitHub. This post may be helpfull.

Here is how autoload.php looks like:

<?php
/**
 * Users who do not have 'composer' to manage dependencies, include this
 * file to provide auto-loading of the classes in this library. 
 */
spl_autoload_register ( function ($class) {
 /*
  * PSR-4 autoloader, based on PHP Framework Interop Group snippet (Under MIT License.)
  * https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md
  */
 $prefix = "Project\";
 $base_dir = __DIR__ . "/src/";
 
 /* Only continue for classes in this namespace */
 $len = strlen ( $prefix );
 if (strncmp ( $prefix, $class, $len ) !== 0) {
  return;
 }
 
 /* Require the file if it exists */
 $relative_class = substr ( $class, $len );
 $file = $base_dir . str_replace ( '\\', '/', $relative_class ) . '.php';
 if (file_exists ( $file )) {
  require $file;
 }
} );
?>

I'd like you to take a look at the '$prefix = "Project\\";'.  What you have to do is just change the "Project" with the prefix used referring to $base_dir directory. The easiest way to find out is by opening the example.

For example, I was using Mike42 library to print to POS printer. Here is just a part of the example code:

<?php
/* Example print-outs using the older bit image print command */
require __DIR__ . '/../autoload.php';
use Mike42\Escpos\Printer;
use Mike42\Escpos\EscposImage;
use Mike42\Escpos\PrintConnectors\FilePrintConnector;

$connector = new FilePrintConnector("php://stdout");
$printer = new Printer($connector);

In Mike42's case, the autoload.php will be:

<?php
/**
 * Users who do not have 'composer' to manage dependencies, include this
 * file to provide auto-loading of the classes in this library. 
 */
spl_autoload_register ( function ($class) {
 /*
  * PSR-4 autoloader, based on PHP Framework Interop Group snippet (Under MIT License.)
  * https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md
  */
 $prefix = "Mike42\";
 $base_dir = __DIR__ . "/src/Mike42/";
 
 /* Only continue for classes in this namespace */
 $len = strlen ( $prefix );
 if (strncmp ( $prefix, $class, $len ) !== 0) {
  return;
 }
 
 /* Require the file if it exists */
 $relative_class = substr ( $class, $len );
 $file = $base_dir . str_replace ( '\\', '/', $relative_class ) . '.php';
 if (file_exists ( $file )) {
  require $file;
 }
} );
?>

The prefix Mike42 refers to directory /src/Mike42.

I hope this can help you

Jumat, 17 Agustus 2018

Direct Print to POS Printer from Javascript on Client Side

As you have already known, web browser is like a sandbox. It is not allowed to access anything else on PC. That means, we need a program or background service as an interface to send the data from the web to printer. mike42 provides perfect PHP library that allows direct print from PHP. Unfortunately, PHP is on server side. We still need this library, since mike42 provides us functions that return ESC/POS data in binary. This data is what we need.

Next, since we want to print from web on client side, we need a way to direct print from javascript and, as I mentioned above, a third party service that allows us sending data to the printer. For that purpose, Kwickpos has that program written in python.

I use POS Printer Taffware ZJ-5890K. It is a low-priced thermal POS Printer and it is a good printer.

These are what we need for the PC on client side:

  1. KwickPython, you can download it from its web or download the script here
  2. install Python. Go googling, download and install the latest version
  3. Install Pywin32. Find the version that is compatible with your Python's version
  4. Install the driver of the POS Printer and share it as "POSPRINTER". You can refer to this tutorial if you have never shared printer before.
  5. After installing all of them, you need to add python's file path to Environment Variables. You can read it here. I'm using windows 8 and tested it in windows 10 too, the file path to python is C:\Users\[username]\AppData\Local\Programs\Python\Python37-32. Replace "[username]" with the real path on your PC. 
Do these steps:
  1. Open cmd console by Winkey-R, type "cmd" and Enter
  2. Make KwickPython cgi-bin directory:C:\KwickPython\htbin
  3. Save KwickPython script as:C:\KwickPython\htbin\kp.py
  4. Start the KwickPython:C:\KwickPython> python -m http.server --cgi 9100
Actually, you can read the more detailed explanation in KwickPython website. The script can do some other things, like return the list of active Printer, so you can choose which printer you want to use. My focus in this post is just how to use it for printing.

I assume, you have already started the KwickPython right now. The script listen to port 9100, you may change the port number if you like.

On Server Side you need mike42 PHP Library, download it here.

I forget to mention earlier, that I'm using CodeIgniter. I put the mike42 PHP Library inside the directory "view". And here are the controller and the view for printing.

Controller:

public function printPOS()
{
 $this->load->view('escpos-php-development/autoload.php');
 $this->load->view('print');
}

escpos-php-development is the name of the directory where library located.
Now here is how the "print.php" looks


print.php:
<?php
use Mike42\Escpos\Printer;
use Mike42\Escpos\PrintConnectors\DummyPrintConnector;
use Mike42\Escpos\CapabilityProfile;

/* Open the printer; this will change depending on how it is connected */

try
{
 $connector = new DummyPrintConnector();
 $profile = CapabilityProfile::load("TSP600");
 $printer = new Printer($connector);

 
 $printer -> text("hallo, direct Print From Javascript\n");
 $printer-> feed(3);

 $data = $connector -> getData();
 $base64data=base64_encode($data);
 $printer -> close();
}
catch(Exception $e)
{
 echo "Couldn't print to this printer: " . $e -&gt getMessage() . "\n";
}
?>
<input type="hidden" id="rawdata" value="<?php echo $base64data;?&gt">


<script>
var dat="";
window.onload = callFunction();

function callFunction()
{
 setInterval(ajax(),500);
}

function ajax()
{
 var rawdat=document.getElementById('rawdata').value;
 var xhttp = new XMLHttpRequest();
   
 url = 'http://localhost:9100/htbin/kp.py';
 xhttp.open("POST", url, false); //browser has to wait until the data finished loaded
 xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
 xhttp.onreadystatechange = function(){
  if(this.readyState==4 && this.status == 200)
  {
   alert(this.responseText);   
  }
  
 }
 
 xhttp.send("p=POSPRINTER&data="+rawdat);
}
</script>

Take a look at the ajax function when it call xhttp.send("p=POSPRINTER&data="+rawdat). the "p" is for the name of the shared Printer, you may change the value of  "p". The "data" is the  bas64 encoded binary data of raw ESC/POS commands.

If you are using chrome, you need to install CORS extension. You need it, because the ajax tries to open a url outside the web application domain. Your web domain may be myweb.com and the ajax will try to access localhost, which is outside myweb.com domain. It may lead to security issues, chrome will warn you by the time you are activating this extension.

Actually that is already everything. You may have some question how to start the KwickPython on window startup or how to start it as windows service, just refer to the KwickPython website and just google to find how to start the script as windows service.

I hope this posting can help you somehow.

[Updated]
RUN KwickPython as a Service

To be able to print on client side, you should activate the KwickPython. On the official Website of KwickPython they already told us that there are two ways to start it automatically. Call it as a job and it will activate the cmd console or call it as service with no cmd console. The main problem if you call it as a job, the service will stop if the console is closed. So, its better if the service keep running although the console is closed. Then we should run it as a service. Unfortunately, it is not that easy to execute a command as a service.

So this is how I do it. I run the KwickPython at the startup as batch job with no console.

  1. There are 3 Files that I need: kp.py that I put inside 'htbin' directory, a bat file to execute the command activating the python service and a vbs file to call the bat file without console.
  2. Download the kp.py and put it inside 'htbin' directory
  3. put the htbin inside c:\KwickPython (like I mentioned above)
  4. Create a bat file and give a name, in my case I name it 'printService.bat'. Write this code:
c:\
cd c:\KwickPython
python -m http.server --cgi 9100

  1. Put the printService.bat fie inside c:\KwickPython
  2. Open Run dialog with win+R and type 'shell:startup'. It will open startup directory, every program that you put inside this directory will be activated at the startup windows.
  3. Create a vbs file inside this directory. I name this file 'printService.vbs'. Write this code inside the file
Dim WinScriptHost
Set WinScriptHost = CreateObject("WScript.Shell")
WinScriptHost.Run Chr(34) & "C:\KwickPython\printService.bat" & Chr(34), 0
Set WinScriptHost = Nothing

That's it. Try to reboot your windows. After your windows finish booting, open cmd and check it using 'netstat -tan' whether port 9100 is already in Listening state. Try to print something. It works fine in my project.

I hope this can help you....

Kamis, 22 Maret 2018

Mendapatkan Password Admin ZTE F609

Pada Umumnya Router ZTE F609 diberikan oleh Indihome ke pelanggannya. Terkadang ada pelanggan yang membutuhkan koneksi VPN untuk mengkoneksikan 2 jaringan lokalnya yang terpisah secara geografis atau memasang Server di Rumah yang ingin diakses via VPN. Sehingga Modem Router tersebut perlu di set ke bridge mode dan dikoneksikan ke router Mikrotik (Pada umumnya router Mikrotik yang digunakan).

Problem:
  1. Pada umumnya akses ke Router yang diberikan Telkom menggunakan username "user" dan password "user"
  2. Username dan password tidak memiliki hak akses sebagai "Administrator", sehingga konfigurasi jaringan WAN tidak bisa dilakukan
Solusinya dapetin username dan password dengan hak akses admin, lakukan steps berikut:
  1. Download aplikasi RouterPassView pada link berikut: www.nirsoft.net
  2. File yang didownload dalam bentuk Rar, silahkan di extract.
  3. siapkan flashdisk dan tancepin di port USB pada modem Router ZTE F609
  4. Buka halaman seperti yang ditunjukan pada gambar dibawah, dan silahkan klik "Start Backup".
     
  5. File hasil backup ada dalam directory "CfgBak" dan nama filenya "usbbak.cfg". File tersebut tidak dapat dibaca dengan menggunakan notepad. Disinilah kita perlu bantuan aplikasi RouterPassView.
  6. Silahkan buka file usbbak.cfg dengan RouterPassView dan find (CTRL+F) "userinfo". Scroll down dikit, nah ketemu deh. Bisa lihat gambar dibawah juga nih contohnya: 

How to Show Password of known Wifi connections on Windows 8 or 10

Quick post, how to show password of known wifi connections on windows 8 or 10. Someone might need this info too.

On previous windows's version, it was easier than on windows 8. Up on windows 8 we can do that through command prompt.

So these are the steps:
  1. open command prompt. Type "cmd" on search menu
  2. type "netsh wlan show profile" to show the name of known wifi connections. Pick the wifi name, that you want to show its password. I'll pick "maira" this time. 


  3. Then continue with this command "netsh wlan show profile "maira" key=clear" , the password will be shown as shown on the picture bellow. 


Minggu, 25 Februari 2018

Play youtube in Background on Android


  1. Don't use You tube app!!!!
  2. Open youtube with Chrome
  3. Request open as Destop Site
  4. Let the music on youtube playing, then open next Tab
  5. Your music might stop by now, don't worry. Look at the top left of your screen. The Volume icon should be shown. Click on it and play the music again. 
  6. Now you're good to open another App.

Selasa, 30 Januari 2018

TWAIN, Accessing Scanner via Web (Windows as client)

I need to develop a web app that should access client's scanner via web.
Since the scanner is installed in client's PC, that means we should use Javascript to do this. The next question is, can javascript access the scanner ??? Unfortunately, javascript can not do that. That means there should be a third party software that is able to provide the scanner as a service. 

There are many good software for that, but most of them are not free. After browsed a while, I finally found someone who developed this software and share it for free.


Yup, its Scan AppForWeb. I have not tried this in my web app actually, but I have tried to install it and it seems good.

So after I read the README, it uses web socket to access the scanner. The Scanner can be accessed via ws://localhost:8181.

To install the software, download Scan_App_SetUp.msi and setup.exe or just download the ScanApps.zip and extract the file. After it installed, open cmd and check netstat -an.

And here is the result:

look at the third last line, the state of port 8181 is LISTENING. It looks really good.

Next, I'll post whether the Web Scanner works or not....hope it works...

Selasa, 23 Januari 2018

codeIgniter, removing index.php in url

source : https://situsali.com/belajar-codeigniter-3-dasar-routing/

The default URL used by CI contains "index.php". This bothers some of us.
So here is how I remove the "index.php" inside the URL.


  • Make sure mod_rewrite module in Apache is already activated. This can be checked in httpd.conf. This file can be found in xampp/apache/conf/httpd.conf. Find a line with this LoadModule rewrite_module modules/mod_rewrite.so. If there is a hashtag at the beginning of the line, remove it. 
  • Restart Apache, if it is necessary 
  • Create a .htaccess file inside the CI folder, at the same level with application directory, system directory, user_guide directory and so on. 
  • Insert this code inside .htaccess: 
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]

  • Finally, go to application/config/config.php. Set the value of $config['index_page'] to '' (blank) --> $config['index_page'] = '';

That's it

Sabtu, 20 Januari 2018

Check whether javascript function exists

if(typeof clearToday !== 'undefined'){
      clearToday();
}

above will check if function clearToday exists before the function executed.

Storing Javascript value into PHP

Short note!
I'm programming a web app for a health clinic and I just had a problem to give a notification sound for the doctor if new patient registered.

I use SSE to update the list of the queuing patients. The number of the queuing patients will be reduced if one patient is served and added if a new patient registered. The notification sound should be ringed once when a new patient registered.

The question is, where should I put the update function since I save the header, the side menu and the body (content) separately.

If I put the update function in the body, the problem is I have to put the update function in every page. Well it is actually not a problem, it is just funny to put the same function in every page.

So I decide to put the function in the header, since every page uses the same header. The problem is wherever I browse through the web app, the notification sound just may only be ringed once!!!! That means, I have to store the current number of the queuing patients as a session variable. That is the solution, but the problem is how I can do that since the Javascript updating the number..???!!!!

For the record, Javascript is client side and php is server side. So it is imposible to save Javascript value into PHP, if I do it via Javascript. That is the second clue. I have to pass the Javascript value to PHP somehow and let the PHP stores the value to a session variable.

So this is how I do that:

  1. Storing: Use AJAX to pass the Javascript value to PHP
  2. Storing: Since I am using MVC, I make a function in Controller just for storing the value to a session variable.
  3. Fetching: Make a Javascript function to fetch the value of the session variable and call it on loading windows. Storing PHP value into Javascript variable should not be a problem. 
  4. Fetching: Put the AJAX function inside SSE and call it if the number of queuing patient is added.

Senin, 08 Januari 2018

Show all HTML DOM childNodes

Everything is node in HTML DOM. To make sure that we get the right childNode, we can show all the childNodes. It really helps everyone who is new with this (me as well).

Best example is shown by W3SCHOOL. It is the link.

Hope it can help you.