Saturday, June 26, 2010

Codeigniter Language Class Bug!

Saya sedang membangun web site yg support 2 bahasa.
Alhasil, sempat dibuat frustasi oleh CI. Setelah
setengah hari berkonsultasi ke google dan forum
hasil nya nihil. Kira2 begini masalah nya:
1. ./system/application/config/config.php
$language = "indonesia"; # default indonesia

2. ./system/application/config/autoload.php
$language = array('caption');

3. ./system/application/language/english/caption_lang.php
$lang['caption_welcome'] = 'Welcome';

4. ./system/application/language/indonesia/caption_lang.php
$lang['caption_welcome'] = 'Selamat datang';

5. ./system/application/controllers/welcome.php
$this->load->library('config');
$this->config->set_item('language','english');
$this->lang->load('caption');

echo $this->lang->line('caption_welcome');

Expected Result:
Welcome

Actual Result:
Selamat datang

Fixes:
create a file Language.php into your ./system/application/library

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* CodeIgniter
*
* An open source application development framework for PHP 4.3.2 or newer
*
* @package CodeIgniter
* @author ExpressionEngine Dev Team
* @copyright Copyright (c) 2008 - 2009, EllisLab, Inc.
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 1.0
* @filesource
*/

// ------------------------------------------------------------------------

/**
* Language Class
*
* @package CodeIgniter
* @subpackage Libraries
* @category Language
* @author ExpressionEngine Dev Team
* @link http://codeigniter.com/user_guide/libraries/language.html
*/
class CI_Language {

var $language = array();
var $is_loaded = array();
var $current_language = '';
var $mode = 'Replacement';

/**
* Constructor
*
* @access public
*/
function CI_Language()
{
log_message('debug', "Replacement of Language Class Initialized");
}

// --------------------------------------------------------------------

/**
* Load a language file
*
* @access public
* @param mixed the name of the language file to be loaded. Can be an array
* @param string the language (english, etc.)
* @return mixed
*/
function load($langfile = '', $idiom = '', $return = FALSE)
{
$langfile = str_replace(EXT, '', str_replace('_lang.', '', $langfile)).'_lang'.EXT;

if (in_array($langfile, $this->is_loaded, TRUE))
{
if($this->current_language == '' ||
$this->current_language == $idiom){

return;
}
}

if ($idiom == '')
{
$CI =& get_instance();
$deft_lang = $CI->config->item('language');
$idiom = ($deft_lang == '') ? 'english' : $deft_lang;
}else{

if($this->current_language != $idiom){

$this->is_loaded = array();
}
}

$this->current_language = $idiom;

// Determine where the language file is and load it
if (file_exists(APPPATH.'language/'.$idiom.'/'.$langfile))
{
include(APPPATH.'language/'.$idiom.'/'.$langfile);
}
else
{
if (file_exists(BASEPATH.'language/'.$idiom.'/'.$langfile))
{
include(BASEPATH.'language/'.$idiom.'/'.$langfile);
}
else
{
show_error('Unable to load the requested language file: language/'.$idiom.'/'.$langfile);
}
}

if ( ! isset($lang))
{
log_message('error', 'Language file contains no data: language/'.$idiom.'/'.$langfile);
return;
}

if ($return == TRUE)
{
return $lang;
}

$this->is_loaded[] = $langfile;
$this->language = array_merge($this->language, $lang);
unset($lang);

log_message('debug', 'Language file loaded: language/'.$idiom.'/'.$langfile);
return TRUE;
}

// --------------------------------------------------------------------

/**
* Fetch a single line of text from the language array
*
* @access public
* @param string $line the language line
* @return string
*/
function line($line = '')
{
$line = ($line == '' OR ! isset($this->language[$line])) ? FALSE : $this->language[$line];
return $line;
}

}
// END Language Class

/* End of file Language.php */
/* Location: ./system/application/libraries/Language.php */
Komentar: Library native saya replace, jadi tidak ada core hack.
perhatikan, saya menambahkan var $current_language yg penggunaannya
cukup desktriptif. Lalu saya menambahkan pengecekan di in_array()
dan ada peng-reset-an
...
if($this->current_language != $idiom){

$this->is_loaded = array();
}
...
utk memastikan ketika terjadi penggantian bahasa, var $lang
yg telah di cache ter-reset. Semoga membantu.
Coding for life, coding with ethic.

Saturday, June 5, 2010

Python, Scrapy Installation Step-by-step

Wahh... kok mainnya sekarang python? Hahhaha
sangat berbisa! Anyway di artikel ini gw
mau bagiin caranya install makhluk yg satu ini.
Sebelumnya apaan sehh itu Scrapy? Gampangnya
light framework utk web crawler! Utk apa tuh
crawler? crawler atau spider crawler biasanya
digunakan utk mengumpulkan informasi dari suatu
web site, entah itu link nya atau content nya.

Informasi ini nanti nya bisa diolah sedemikian
rupa utk keperluan tertentu. Misalkan utk statistik
penggunaan kata yg di mana akan dibobotkan dan
dijadikan misalnya utk data penyusun "tag clouds".
Ok, gw akan tunjukkin gimana cara install nya di
windows.

1. install python dari sini unduh nya http://www.python.org/download/,
gw seh pake nya python2.6 run .exe atau .msi nya
2. Twisted for windows
unduh dan run .msi nya
3. Zope.interface
nah yg ini butuh penjelasan lbh lanjut, pastikan download source nya.
Setelah itu unzip lalu ketik ini di command line "python setup.py install"
4. libxml2 for windows
unduh dan run .msi nya
5. PyOpenSSL for Windows
unduh dan run .msi nya
6. Scrapy-0.8.win32.exe
unduh dan run .msi nya
7. Scrapy-0.8 source
unduh, unzip dan run ini di command line "python setup.py install"
8. masih di dalam direktori hasil unzip source Scrapy, buka direktori example scripts,
lalu ketik ini "python count_and_follow_links.py http://adesanto-asman.blogspot.com 2"
atau "python count_and_follow_links.py" nanti akan ada help yg muncul

Sekedar tambahan, utk file dg extension
".egg" adalah merupakan file yg ter-zip.
Utk unzip nya pakai easy_install
Selamat mencoba dan happy crawling.
Coding for life, coding with ethic.

Joomla! Embed Javascript in Article

Buat sharing aja. Kalau di dalam artikel
dapat di sisipkan Javascript. Caranya:
1. Login di administrator site.
2. Buka artikel manager.
3. Tulis baru atau edit yg sudah ada.
4. Plugin editor akan muncul,
Klick "html", muncul window utk
meng-edit Html source.
5. Masukan tag script selayaknya kita
menyisipkan Javascript.
<script type="text/javascript">
alert("Hello, i've been embedded in an article!");
</script>
6. Save atau apply.
7. Buka artikel tersebut melalui
front page.
8. Ketika artikel selesai load,
seharus nya alert box akan muncul.

Semoga membantu. Coding for life, coding with ethic.

Friday, May 28, 2010

jQuery Rebind After Ajax Call

Hampir 2 jam lamanya, gw muter2 di coding
JAVASCRIPT. Bingung kenapa innerHTML yg
di "isi" oleh AJAX yg terdapat sisipan
JAVASCRIPT ga jalan.Nah utk lebih jelas nya
silahkan dicuba code di bawah ini.
Sebelumnya pastikan jQuery sudah
ter-"install" jika belum silahkan download
di sini Download jQuery.
<!-- file: index.html -->
<html>
<head>
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
</head>
<body>
<div id="test1">
Mouse over me please
</div>
<div id="data-container">
</div>
</body>
<script type="text/javascript">
$('#test1').mouseover(function(){

alert('test1 triggered');

$.post('data.html',function(data){

$('#data-container').html(data);
});
});
</script>
</html>
<!-- end of: index.html -->

<!-- file: data.html -->
<div id="test2">Request Complete, try mouse over to trigger alert</div>
<script type="text/javascript">
$('#test2').mouseover(function(){

alert('test2 triggered');
});
</script>
<!-- end of: data.html -->
Humm... aneh kan? Fungsi alert seakan2 tidak
tereksekusi. Nah solusi nya di cuba code
di bawah ini.
<!-- file: index.html -->
<html>
<head>
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
</head>
<body>
<div id="test1">
Mouse over me please
</div>
<div id="data-container">
</div>
</body>
<script type="text/javascript">
$('#test1').mouseover(function(){

alert('test1 triggered');

$('#data-container').load('data.html',function(data){

// Re-Bind
$('#test2').mouseover(function(){

alert('test2 triggered');
});
});
});
</script>
</html>
<!-- end of: index.html -->

<!-- file: data.html -->
<div id="test2">Request Complete, try mouse over to trigger alert</div>
<!-- end of: data.html -->
Semoga membantu.
Coding for life, coding with ethic.

Sunday, May 16, 2010

jQuery Simple Modal

Sudah pernah dengar jQuery? Kalo belum segera ke TKP!
jQuery: The Write Less, Do More, JavaScript Library
Karena web application akan terasa sperti desktop application.
Belum lagi dukungan utk Ajax yg super simple.
Benar2 buat life so easier...

Nah setelah download tuh jQuery, gw mau bahas neh
tentang modal window. Apa sehh modal window? Kalo yg
pernah megang java pasti tau banget nehh. Modal window
itu adalah dimana user "dipaksa" antar muka
terhadap suatu window saja. Contoh nya, cuba
taruh script ini.
<script>alert("Native modal");</script>

Udah dapet dunk bayangan nya? cuba dehh klik area
lain tapi masih dalam scope browser tsb yahh,
atau parent application nya. Nahh kl udah dapet
gambarannya, skg bagaimana caranya supaya tuh
modal muncul sesuai dg design kita? Kalau
dengan jQuery hanya cukup dg
$("#element-id").modal();

Se-simple itu kah? Lahh judul artikel ini apa?
Simple Modal! hahahahhaha. Ini referensi nya
langsung, komunitasweb.com . Hope you guys enjoy
this article.

Coding for life, coding with ethic.

Sunday, May 2, 2010

Codeigniter Oracle Transaction BUG

Guys, ini baru ketemuin BUG. Khusus nya
utk Driver Database Oracle, OCI8.
Seharus nya transaksi yg di awali
dg trans_start(TRUE) tidak akan ter-COMMIT.
$this->db->trans_start(TRUE);
$this->db->simple_query("insert into test
(id,name)
values
('1','ade1') ");
$this->db->simple_query("insert into test
(id,name)
values
('1','ade2') ");
$this->db->simple_query("insert into test
(id,name)
values
('1','ade3') ");
$this->db->trans_complete();

Expected result:
rollback

Actual result:
rollback

Semua berjalan lancar, transaksi di rollback.
Lohh mana BUG nya? Nahh cuba sisipkan
'SELECT' query di antara nya :D.
Sudah terlihat BUG nya? Query 'INSERT'
sebelum 'SELECT' ter-COMMIT. Di mana seharus nya
tidak boleh!!! Ceritanya begini, misalkan
kita ada transaksi seperti ini:
$this->db->trans_start(TRUE);
$this->db->simple_query("insert into test
(id,name)
values
('1','ade1') ");
$this->db->simple_query("insert into test
(id,name)
values
('1','ade2') ");
$result = $this->db->query("select * from test");
$this->db->simple_query("insert into test
(id,name)
values
('1','ade3') ");
$this->db->trans_complete();

Expected result:
rollback

Actual result:
2 rows inserted

Nah setelah saya telusurin driver nya.
Ternyata BUG nya ada di
/system/database/driver/oci8/oci8_result.php
line : 46 dan 50. Fungsi ociexecute bila hanya terima
1 parameter maka parameter ke 2 nya di set
menjadi OCI_COMMIT_ON_SUCCESS. Kebayangkan?
Jadi seluruh transaksi insert akan ter-COMMIT
walaupun trans_complete belum terpanggil.

Solusi nya cukup rubah line 46 dan 50,
@ociexecute($this->stmt_id);
menjadi
@ociexecute($this->stmt_id, OCI_DEFAULT);

Di execute lagi query di atas yg ada 'SELECT'
query di antaranya dan expected result nya
tercapai.

Coding for life, coding with ethic.

Thursday, April 29, 2010

Joomla Flashdata

Artikel ini gw tulis berhubung sdg giat2 nya
menggunakan Joomla utk bbrp project gw.
Begini, ktika menggunakan CI gw dapetin fitur
yg amat sangat membantu, Flashdata.

Nah pas googling... kok tak kunjung dapet tuh
yg berkaitan dg Flashdata. Buntut2 nya gw liat2
isinya flashdata di CI, trus gw tulis sendiri
utk Joomla. Langsung aja.
/* buat dir baru di path ini flashdata/ */
/joomla/libraries/flashdata/

/* tambahkan flashdata.php */
class Flashdata {

public $flashdata_key = 'flash_';
public $userdata = array();

function __construct(){


}

function set_flashdata($newdata = array(), $newval = '')
{
if (is_string($newdata))
{
$newdata = array($newdata => $newval);
}

if (count($newdata) > 0)
{
foreach ($newdata as $key => $val)
{
$flashdata_key = $this->flashdata_key.$key;
$this->set_userdata($flashdata_key, $val);
}
}
}

function set_userdata($newdata = array(), $newval = '')
{
if (is_string($newdata))
{
$newdata = array($newdata => $newval);
}

if (count($newdata) > 0)
{
foreach ($newdata as $key => $val)
{
$this->userdata[$key] = $val;
}
}

$_SESSION['user_flashdata'] = serialize($this->userdata);
}

function flashdata($key)
{
$flashdata_key = $this->flashdata_key.$key;

$temp = unserialize($_SESSION['user_flashdata']);

$value = $temp[$flashdata_key];

unset($temp[$flashdata_key]);

return $value;
}
}

Cara penggunaan:
tambah kan external link melalui administrator GUI dari joomla
utk dapat masuk ke component anda.

Di dalam component
/* /joomla/components/com_komponenku/komponenku.html.php */
class Komponenku_HTML{

function execute($task){

switch($task){
...
default:

$flashdata_ku = JFlashdata::flashdata('test');

if(!empty($flashdata_ku)){

echo $flashdata_ku;
}else{

JFlashdata::set_flashdata('test','Pesan ku');
header('location : '.JURI::root().'index.php?option=com_komponenku');
}
}
}
}
Nah utk class Flashdata masih jauh dari yg CI.
Tapi dg contoh yg di atas dan gw pribadi gunakan,
sudah memberikan suatu kepuasan. Karena sekali lagi
fitur ini sangat membantu.

Coding for life, coding with ethic.

Thursday, April 22, 2010

Codeigniter The Importance of Flashdata

Mungkin byk yg belum mengetahui,
bhw CI ada fitur yg amat sangat membantu
dalam status/message handling. Yup! flashdata,
fitur ini sungguh membuat kecanduan hehehhehe.
Masalah nya ampe bela2 in, utk buat di Joomla.

Sekilas apa itu flashdata.
"Session data that will only be available for the next server request,
and are then automatically cleared.
These can be very useful,
and are typically used for informational or
status messages (for example: "record 2 deleted")."
Cukup deskriptif, B.Ing menjadi keharusan utk programmer.
Ok, lsg ke implementasi nya aja.
/* controllers/welcome.php */
...
$this->session->set_flashdata('pesan_ku', 'Hello Adesanto');
$this->load->view('welcome');
...

/* views/welcome.html.php */
<?php
echo '1st message, '.$this->session->flashdata('pesan_ku').'<br/>';
echo '2nd message, '.$this->session->flashdata('pesan_ku').'<br/>';
?>

Output:
1st message, Hello Adesanto
2nd message,
Perhatikan setelah pesan "1st message " terdapat data dari flashdata,
tetapi 2nd tidak. Jadi ketika flashdata di panggil maka data terkait
dg key (dlm contoh ini, "pesan_ku") akan lsg terhapus. Fitur ini
sungguh amat sangat berguna ketika anda melakukan insert ke DB
dan setelah itu me-redirect user ke halaman tertentu. Cukup passing
status dari insert ke flashdata dan di tampilkan pesannya di halaman
yg di tuju. Tentunya fitur flashdata ini dapat mempertahankan data
agar tidak lsg terhapus setelah di panggil. Lsg di telusuri aja
user guide dari CI.

Memang CI sesuai dg motonya, "Lightweight and small footprints".
Coding for life, coding with ethic.

Tuesday, April 20, 2010

Codeigniter No More POP-UP Pains

Huhh, hampir semua client yg gw pegang selalu
telp dan menanyakan kenapa ini ga jalan, kenapa
itu ga bisa. Buntut2 nya ehh krn pop-up nya di
block ama tuhh browser. Emang sihh jaman nya
pop-up udah lewat, byk an diblock ama browser.

Karena begitu tinggi nya masalah yg disebabkan
karena pop-up yg ke block. Maka skg gw mau bagiin,
bagaimana supaya kita tidak bergantung pada pop-up
tetapi masih memiliki fitur seperti pop-up.

Ok, cara ini kita tempuh dg kerjasama CSS, AJAX
dan pasti nya PHP. Kita ga lama2 lagi lsg aja.
Struktur CI gw sperti ini,

CI/
CSS/
file_css_pop_up.css
JAVASCRIPT/
pop_up_handler.js
SYSTEM/
APPLICATION/
CONTROLLERS/
welcome.php
...
...
...

Gw kluarin CSS dan JAVASCRIPT dari folder
system/application krn utk alasan security aja sehh.
Coba aja di cek user guide dari CI, mereka memang
menyarankan itu di luar folder system.

/* file_css_pop_up.css */
#pop-up{

display : none;
overflow : auto;
padding-left : 10px;
padding-bottom : 10px;
background-color: #DDF;
border : 1px solid rgb(100,100,225);
Z-Index : 24;
top : 30%;
left : 10%;
width : 80%;
height : 60%;
position : absolute;
}
/* end of css */

/* pop_up_handler.js */
var GMisc={

// _ROOT silahkan di sesuiakan sendiri
_ROOT : 'http://localhost/ci_svc/',
_DEFAULT_POPUP_ID : 'pop-up',
_DEFAULT_POPUP_CONTENT_ID : 'pop-up-content',
_VK_ESC_KEY : 27,
_LOADING_TEXT_STATUS : 'Please wait, loading...',

escKey_kill_popup : function (event,
id){

if(event.which){

keynum = event.which;

if(keynum == this._VK_ESC_KEY){

id = document.getElementById(id);

id.style.display = 'none';
id.innerHTML = this._LOADING_TEXT_STATUS;
}
}
}
}

var MiscControllers={

set_show_id : function (id_popup, str_mode){

id_popup = document.getElementById(id_popup);

if(str_mode == '1'){

id_popup.style.display = 'block';
}else{

id_popup.style.display = 'none';
}
}

set_some_data : function(id_object){

var str_data = 'You could replace this static
data with your ajax call or else
';
id_object = document.getElementById(id_object);
id_object.innerHTML = str_data;
}
}
/* end of js */

/* controllers/welcome.php */
...
function index(){
$this->load->view('footer');
$this->load->view('includes');
$this->load->view('content');
$this->load->view('footer');
}
...
/* end of controllers */

/* view/includes.php */

<script type="text/javascript"
src="<?=base_url() ?>javascript/pop_up_handler.js">
</script>
<link rel="stylesheet"
type="text/css"
href="<?=base_url() ?>css/file_css_pop_up.css" />

/* end of view */

/* view/content.php */

<body onKeyDown='GMisc.escKey_kill_popup(event,
GMisc._DEFAULT_POPUP_ID)'>

<div id='content-wrapper'>
<div id='content'>
<?php
// gw ga specified type='submit'
// krn emg supaya ini button ga submit
// setelah di klik atau mungkin utk safe
// di akhir dari JS nya
// ditambah dg "return false;"
$button_js =
"\" onClick='MiscControllers.set_show_id(
GMisc._DEFAULT_POPUP_ID, 1);
MiscControllers.set_some_data(
GMisc._DEFAULT_POPUP_CONTENT_ID)' \"";

$button_attributes =
array('name' => 'dummy',
'content' => 'Klik gw donk!!!',
$button_js);
?>
</div>
</div>

<div id='pop-up'>
Press (ESC) to close

<div id='pop-up-content'>
Please wait, loading...
</div>

</div>

</body>
/* end of view */

Message "Please wait, loading..." mungkin tidak akan terlihat,
krn proses id_object.innerHTML = ... ini sangat cepat.
Tetapi akan terlihat bila data yg hendak di munculkan bersumber
dari ajax call. Mungkin kalau ada masukan atau komentar silahkan,
jgn ragu. Thx.
Coding for life, coding with ethic.

Monday, April 19, 2010

Codeigniter Awkward Form Helper

Codeigniter awkward form helper

Bagaimana kabar nya para pembaca yg budiman?
Wuihh prolog yg mantab :D (narsis.net/ON).
Anyway sperti nya klise bukan? Nah persis
seperti yg gw alamin. Di User Guide CI kl
boleh di perhatiin, khusus nya form helper.

Disana ada tertera byk contoh guide,
dari <form>,<input>...<hidden>.
Yg mau gw garis bawahin adalah ktika
setup "$attributes = array(...);".
Gw cuba utk menambahkan attribut javascript
utk salah satu button,
ehh yg ada malahan <button> -nya di setup
ngawur atau mungkin gw nya yg ngawur yahh?
Ini code yg gw setup dan berikut hasil
html nya.

@test_view.php
...
$js_grant_button =
" onClick= 'MiscControllers.set_show_id(
GMisc._DEFAULT_POPUP_ID,1);
Menu_Y3.init_grant_menu(
GMisc._DEFAULT_POPUP_CONTENT_ID);
return false;' ";

$grant_button = array('name' =>
'grant_button',
'value' =>
$access->levelmn,
'content' =>
'Users',
$js_grant_button);

echo form_button($grant_button);
...

Output

<button
name="grant_button"
type="button"
value="3"
0=" onClick= '
MiscControllers.set_show_id(
GMisc._DEFAULT_POPUP_ID,1);
Menu_Y3.init_grant_menu(
GMisc._DEFAULT_POPUP_CONTENT_ID);
return false;' " >Users</button>
*Perhatikan 0="..."
**Mohon maklum jika semua di susun ke bawah


Aneh bukan? seharus nya kontruksinya benar.
Tapi entah kenapa jadi ngawur, dengan muncul nya
'0=" onClick=..."'. Nah ini solusinya.

@test_view.php
...
// perhatikan saya menambahkan \" diawal dan sebelum
// akhir daripada "
$js_grant_button =
"\" onClick= 'MiscControllers.set_show_id(
GMisc._DEFAULT_POPUP_ID,1);
Menu_Y3.init_grant_menu(
GMisc._DEFAULT_POPUP_CONTENT_ID);
return false;' \"";

$grant_button = array('name' =>
'grant_button',
'value' =>
$access->levelmn,
'content' =>
'Users',
$js_grant_button);

echo form_button($grant_button);
...

Output

<button
name="grant_button"
type="button"
value="3"
0=""
onClick= '
MiscControllers.set_show_id(
GMisc._DEFAULT_POPUP_ID,1);
Menu_Y3.init_grant_menu(
GMisc._DEFAULT_POPUP_CONTENT_ID);
return false;'
"" >Users</button>
*Perhatikan 0="" dan akhir nya ""


Mungkin ada yg mau kasih masukan silahkan.
Coding for life, coding with ethic.

Friday, April 16, 2010

Codeigniter Pass Object through SESSION variable how to

Codeigniter Can not pass Object through SESSION variable

Untuk yg kesulitan pass object dari controller ke view,
via session. Ini obat nya,

// controller file mu, test1.php
// Location: ./system/application/controllers/test1.php
...
$buffer = array();

$dummy_object = new stdClass;
$dummy_object->name = 'ade1';
$dummy_object->id = 'ADEX1';

array_push($buffer, $dummy_object);

$dummy_object->name = 'ade2';
$dummy_object->id = 'ADEX2';

array_push($buffer, $dummy_object);

/**
* Kalau passing nya spt ini pasti error
* can't convert object to string
*
* $this->session->set_userdata('passed_object', $buffer);
*
* Jadi gimana?
*/

$this->session->set_userdata('passed_object', serialize($buffer));
...
?>

// controller file mu, test2.php
// Location: ./system/application/controllers/test2.php
...

/**
* utk mengambil kembali data nya dlm object tinggal
* di unserialize :D
*/

$passed_object = $this->session->userdata('passed_object', unserialize($buffer));
...
?>


Smoga obat nya ampuh.

Coding for life, coding with ethic.