Speedy Alert

Koneksi Telkom Speedy dipengaruhi ketinggian laut? hmm, nggak ngerti deh bagaimana hubungannya. Tapi itu yang dibilang petugas Telkom saat menginstal Telkom Speedy di rumah saya kemarin. Memang jarak rumah cuma beberapa ratus meter dari pinggir laut. Tapi sejauh ini nggak ada masalah tuh. Dan cukup mengejutkan bagi saya, ternyata koneksinya lumayan cepat, hehe.

Eniwey, kalau anda seperti saya yang nggak pernah berhasil pake Speedy Alert, skrip berikut mungkin berguna untuk memantau penggunaan Speedy. Oya, pakai Zend Framework ya.

function getSpeedyUsage($username,$password)
{
  $url = "http://portal.telkomspeedy.com/index.php?flash=-1";

  $client = new Zend_Http_Client($url, array(
    'maxredirects' => 0,
    'timeout'      => 30));

  $client->setParameterPost(array(
    'username'       => $username,
    'password'      => $password,
    'login'             => '    Login    '
  ));

  $response = $client->request('POST');
  $body = $response->getBody();

  $html = str_replace("\n","",$body);
  preg_match_all("|<td class=\"data\"[^>]+>(.*)</td>|U",$html,$regs);

  $info = array();
  $info['pemakaian']['persen'] 	= $regs[1][1];
  $info['pemakaian']['besar'] 	= $regs[1][3];
  $info['limit'] = $regs[1][4];
  $info['kelebihan'] = $regs[1][5];

  return $info;
}

Penggunaannya seperti berikut:

<?php
require_once 'Zend/Http/Client.php';

/************** ubah di sini **************/
$username = "XXXXXXXXXXXX@telkom.net";
$password = "hewhomustnotbenamed";
/******************************************/

$info = getSpeedyUsage($username,$password);

print_r($info);

?>

Keluarannya kurang lebih seperti ini:

Array
(
    [pemakaian] => Array
        (
            [persen] => 17,93%
            [besar] => 179,28 MB
        )

    [limit] => 1.000 MB
    [kelebihan] => 0,00 MB
)

Understanding Zend_Controller (Part I)

Zend_Controller is the heart of Zend Framework's MVC system. To understand why and how Zend_Controller works you need to have a basic knowledge of MVC. But you'll get more in-depth idea of MVC by starting to write codes anyway.

So, let's start by creating file system layout. Here's my simple layout:

application/
  controllers/
    IndexController.php
    FooController.php
  views/
    scripts/
      index/
        index.phtml
      foo/
        bar.phtml
library/
  Zend/
.htaccess
index.php

To work with Zend_Controller you need to create a rewrite roules in .htaccess file,

RewriteEngine on
RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php

I'm assuming that we use Apache mod_rewrite here, you might want to look other configuration for different web server here.

index.php is our bootstrap file where all requests are routed through. It controls all the workflows. Open up your editor and write this code,

<?php
if ( ! defined( "PATH_SEPARATOR" ) ) {
  if ( strpos( $_ENV[ "OS" ], "Win" ) !== false )
    define( "PATH_SEPARATOR", ";" );
  else
    define( "PATH_SEPARATOR", ":" );
}

set_include_path(get_include_path() . PATH_SEPARATOR . "library");

require_once 'Zend/Controller/Front.php';
Zend_Controller_Front::run('application/controllers');

Zend_Controller_Front::run is a shortcut to tell the controller to search controller files in application/controllers directory for each request and dispatch it.

By default, the first segment of a URL path maps to a controller, and the second to an action. For example, given the URL http://www.example.com/foo/bar, the path is /foo/bar, which will map to the controller foo and the action bar. If no action is provided, the action index is assumed, and if no controller is provided, the controller index is assumed (following the Apache convention that maps a DirectoryIndex automatically).

So, http://www.example.com/foo will map to the controller foo and the action index. While http://www.example.com will map to the controller index and the action index.

By default, the controller files reside on the directory which we declared in Zend_Controller_Front::run method. The file name use the the controller name with uppercase on the first letter added with Controller words. For example, URL http://www.example.com/foo will search FooController.php in application/controllers directory. While http://www.example.com will search IndexController.php.

The next step is to write the action controller, the actual code for handling the request. First, let's open up application/controllers/IndexController.php and enter the following,

<?php
require_once 'Zend/Controller/Action.php';

class IndexController extends Zend_Controller_Action
{
  public function indexAction()
  {
  }
}

As you might suspect, indexAction method is the action controller, where executed for index action, i.e where the URL is http://www.example.com

Similarly, you can handle URL http://www.example.com/foo/bar by writing this code into application/controllers/FooController.php,

<?php
require_once 'Zend/Controller/Action.php';

class FooController extends Zend_Controller_Action
{
  public function barAction()
  {
  }
}

Now, if you access http://www.example.com/foo/bar you'll get,

Fatal error: Uncaught exception 'Zend_Controller_Dispatcher_Exception' with message 'Invalid controller specified (error)' in ...

Good, don't worry about the error. It tells you that you're missing something. But before we get to that, it is a good practice to write a controller to handle such errors. By default, Zend_Controller will execute errorAction() method in ErrorController.php when it can't find the appropriate controller files or when something is wrong. So open up application/controllers/ErrorController.php and write the following,

<?php
require_once 'Zend/Controller/Action.php';

class ErrorController extends Zend_Controller_Action
{
  public function errorAction()
  {
    die("An error occurred; please try again later.");
  }
}

Now, if you access URL like this http://www.example.com/none/nothing, you'll get,

An error occurred; please try again later.

No, you can't treat this as 404 Not Found like. Because it's executed not only when the controller can not be found, but also when there's something missing in your codes. For example when you forget the view parts.

Right, by default ViewRenderer action helper is enabled. What this means is that by simply defining an action method and a corresponding view script, you will immediately get content rendered. By default, Zend_View is used as the View layer in the MVC. The ViewRenderer does some magic, and uses the controller name (e.g., foo) and the current action name (e.g., bar) to determine what template to pull. By default, templates end in the .phtml extension, so this means that, http://www.example.com/foo/bar will render the template in views/scripts/foo/bar.phtml.

So, let's open up views/scripts/foo/bar.phtml file and write the following templates,

<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>My first Zend Framework App</title>
</head>
<body>
    <p>You say foo bar!</p>
</body>
</html>

And now you can view your site http://www.example.com/foo/bar, yes it says

You say foo bar!

Great!

That's it. Now you have the basic concept of how Zend_Controller works. As you might notice, i say "by default" many times, this is because you can change the way it works according to your needs. All by extending the abstract and interface class. We'll talk more about this on later post.

Setting Up Zend Framework

I still see some people having a hard time using Zend Framework, so i'll share some of my experience using ZF. Hope this will help.

Let's start with the easy and basic one, setting up ZF. There's two simple way of doing this:

First, download the latest stable release here. It's available in both .zip and .tar.gz formats. Extract the files.

Second, once you have a copy of the ZF available, your application needs to be able to access the framework classes (in library/Zend folder). There are several ways to do this, but assuming you don't have control over PHP configuration in your server all you need to do is using set_include_path function to include the ZF classes.

If you're using Linux,

set_include_path(get_include_path().":library");

or in Windows,

set_include_path(get_include_path().";library");

or you can make your apps compatible with both OS, by determining the path separator, like this:

if ( ! defined( "PATH_SEPARATOR" ) ) {
  if ( strpos( $_ENV[ "OS" ], "Win" ) !== false )
    define( "PATH_SEPARATOR", ";" );
  else
    define( "PATH_SEPARATOR", ":" );
}

set_include_path(get_include_path() . PATH_SEPARATOR . "library");

That's it, you're set to go.