الخميس، 26 ديسمبر 2013

فئة لإنشاء صورة والكتابة عليها

اليوم سأشرح لكم فئة/كلاس لإنشاء صورة والكتابة عليها..

كثيرة هي الأمثلة والفئات التي تتعامل مع الصور والنصوص، لكن هذه الفئة تقسم المهام المختلفة لفئات تتخصص كل فئة تقوم بعمل معين لتتكامل الفئات المختلفة مع بعضها..

ملاحظة (لا يشترط ترتيب استخدام الدوال/الوظائف)

اسم الفئة PNGوهي تنشئ صور من النوع png..

نأتي الآن لطريقة الإستخدام:

$png = new PNG();
- انشاء نسخة من الفئة:
$png->size->set(int width, int height, [int quality]);

- تحديد حجم الصورة: وتأخذ المعاملات التالية (العرض، الطول، الجودة:إختياري)

وتتراوح الجودة بين القيمتين= [0-9]

0 : جودة أصلية (بدون ضغط)

1-9: ضغط الصورة (يستهلك الذاكرة إذا كان حجم الصورة كبير)


$png->color->set(int red, int green, int blue);

تحديد اللون: (احمر، اخضر، ازرق)

حيث يتكون اللون من خليط من ثلاثة ألوان رئيسية وتتراوح قيمة اللون الواحد من [0-255]



$png->text->set(int font_size, string text);

- إضافة نص: (حجم الخط، النص)

$png->text->setPos(int x, int y);

تحديد موضع النص: (س، ص)

$png->text->align(boolean horizontal, boolean vertical, [boolean auto_correct]);

توسيط الخط: (افقي، عمودي، تصحيح تلقائي:إختياري)

تستخدم هذه الدالة/الوظيفة لتوسيط الخط في الصورة افقياً أو عمودياً أو كلاهما والمعامل الأخير لتصحيح خطأ صغير في موقع النص.

$png->text->correctPos(int x, int y);

تعديل موقع النص: (س، ص)

يستخدم لازاحة موقع النص ويمكن أن يأخذ قيم سالبة.

إذا كان الخط موسطاً فإنه يضيف القيم في هذه الدالة لإزاحة موضع الخط قليلاً عن الوسط.

$png->text->setAngle(int degree);

تدوير النص: درجة الدوران: [360:0]، [-1:-360]

ومعامل هذه الدالة/الوظيفة يقبل القيم السالبة أيضاً

$png->text->reverse();

قلب النص أو ترتيب مواضع الحروف بالعكس:

يستفاد منه لتصحيح اتجاه الخط العربي (لكن الكلاس لا يدعم اتصال الحروف في اللغة العربية)

$png->text->color->set(int red, int green, int blue);
تحديد لون الخط: (أحمر، اخضر، ازرق)
$png->text->font->set(string font_path.ttf');

تحديد مسار الخط لاستخدام خط معين (مسار الخط)

يجب أن تحدد مسار للخط لاستخدامه وأن يكون من النوع ttf

إذا لم تقم بتحديد مسار الخط فسيتم استخدام خط افتراضي من خطوط النظام لكن حجمه يأخذ قيمة من [1-6] فقط.

$png->execute(string image_path);

تنفيذ الصورة ([مسار الصورة])

إذا وضعت اسم لمسار الصورة فسيتم حفظ الصورة في نفس المسار وسيستبدل الصورة الموجودة..

إذا تركت المعامل فارغاً فسيتم إرجاع سلسة نصية خاصة بالصورة، وقد تم معالجة الملف لكي تظهر الصورة في المتصفح.


يرجى كتابة استفساراتكم في التعليقات..

الكلاس كاملاً في الرابط التالي:

تنزيل التطبيق كاملا


الأحد، 17 نوفمبر 2013

كلاس/فئة لتحويل شكل الروابط CleanURL

السلام عليكم، اقدم لكم اليوم كلاس/فئة لتحويل شكل الروابط، فهناك ما يسمى بـ clean url وهي روابط صديقة لمحركات البحث ويكون بالشكل التالي:

 http://www.site.com/artical/details/231  

بينما الشكل العادي للروابط يكون على النحو التالي:

 http://www.site.com/artical.php?show=details&id=231  

تعريف المتغيرات


 $link->define("
    str show;
    int id;
");  

يجب تعريف متغيرات الرابط التي تستخدمها من خلال الدالة define وذلك لحماية المتغيرات
وتسمح الدالة define بإضافة انواع عديدة لغرض الحماية كل متغير له اسم ونوع فالرابط التالي:

 www.site.com/artical.php?show=details&id=231  

حيث وأن الرابط يحتوي على المتغيرات/المعاملات التالية:
- show متغير نصي
- id  متغير رقمي

اختيار وتغيير شكل الرابط


 $link->setURL('http://www.site.com/?id=231', CleanURL::SHORT);  

تستخدم الدالة setURL لتغيير شكل الرابط ولها ثلاثة معاملات
- الأول تضع فيه الرابط.
- الثاني لتحديد شكل الرابط، وهو يأخذ احدى قيمتين:
* CleanURL::SHORT وهو عبارة عن القيمة 1
* CleanURL::LONG وهو عبارة عن القيمة 2.
- الثالث يستخدم ليقوم بالتحويل قسراً حيث أن الدالة لا تقوم بتحويل أنواع الروابط الخارجية،
ويقتصر على تحويل الروابط الداخلية فقط في حالة عدم إعطاء المعامل الثالث القيمة true.
يجب ان تكون معاملات الرابط الخارجي مشابهة للمعاملات التي تم تعريفها في الدالة define.

تحديد شكل لجميع الروابط اللاحقة


 $link->setType(CleanURL::LONG);  

يمكن استخدام الدالة setType لتحديد شكل جميع الروابط، وتبقى الأولوية للدالة setURL لتحديد شكل الرابط.
وعند استخدام الدالة setType فلا تحتاج لتحديد شكل الرابط في الدالة setURL. استبعاد مسار أو اسم ملف

 $link->exclusionPath( 'forum/thread');  

إذا كان هناك مسار لمجلد معين فيجب تحديده كمسار لكي يتم استبعاده من عملية التحويل، فالرابط التالي:

 http://mysite/forum/thread/512  

يحتوي على مسار

 form/thread  

ويحتوي على متغير

 id=512  

لذا نستخدم الدالة exclusionPath ونحدد المسار المراد استبعاده

 $link->exclusionPath('artical.php', '.php');  

يحتلف تطبيق الدالة exclusionPath على الروابط الطويلة حيث يمكن استبعاد مسار وحذف جزء منه
فمثلاً إذا أردنا تحويل الرابط:

 http://www.site.com/artical.php?show=details&id=231  

ليكون على الشكل :

 www.site.com/artical/details/231  

يجب استبعاد المسار artical.php واستبعاد اللاحقة .php ايضاً لذا نستخدم الدالة exclusionPath.

ملاحظات للتطوير 

بقي التذكير بأنه في حالة رغبتك بتطوير هذا الكلاس تستطيع استخدام الدالتين _short2long و _long2short لتحويل متغيرات الرابط، حيث تقوم كل دالة بتغيير نوع الرابط للشكل المناسب ولاحاجة للتعديل عليهما، وما عدا ذلك فيمكنك تغييره حسب الحاجة.

 كود الكلاس/الفئة CleanURL


<?php

/* ***********************************
 *  Author    : <HishamDalal@gmail.com>
 * Project Name    : CleanURL
 *  Version    : 1.0
 *  Date        : 2013-11-10 13:10
 * *********************************** */

class CleanURL {
    
    const SHORT = 1;
    const LONG = 2;
    // $link_types Would be like this array Ex. array('page'=>1, 'cat'=>'news', 'id'=>23);
    private $link_types = array();
    private $type = 0;
    private $full_url = null;
    private $site_name = null;
    private $exclusion_path = null;
    private $remove_from_path = null;
    
    //------------------------------------------------------------------//
    // This function has an effect that change URL type, 
    //so you don't need to mention the type in second parameter when you use the function "set" 
    function setType($to){
        $to = intval($to);
        if($to == CleanURL::SHORT || $to == CleanURL::LONG){
            $this->type = $to;
        }
    }
    //------------------------------------------------------------------//
    // Used to define URL parameter types
    function define($strCode){
        preg_match_all("/([\w]+)[\s]+([\w]+);/s", $strCode, $m);
        if(isset($m[1]) && isset($m[2])){
            $this->link_types = array_combine($m[2], $m[1]);
        }
    }
    //------------------------------------------------------------------//
    // Make a decision 
    private function _set($link, $type=0) {
    
        if($type==CleanURL::LONG){
            return $this->_short2long($link);
            
        }elseif($type==CleanURL::SHORT){
            return $this->_long2short($link);

        }elseif($this->type==CleanURL::LONG){
            return $this->_short2long($link);
            
        }elseif($this->type==CleanURL::SHORT){
            return $this->_long2short($link);
        }

        return $link;
    }
    //------------------------------------------------------------------//
    private function _short2long($link) {
        //Find wrong sign
        if(strpos($link, '&')){    return $link;    }
        
        $link = trim($link, '/');
        $ary = explode('/', $link);
        if(is_array($ary) && count($ary)>1){
        $i=0;
        $link = '?';
        foreach($this->link_types as $key=>$type){
            $myKey = @$ary[$i];
            if(isset($myKey)){
                $value = $this->_applayVarType($myKey, $type);
                $link .= $key.'='.$value.'&';
            }
            $i++;
        }
        $link = rtrim($link, '&');
        }
        return $link;
    }
    //------------------------------------------------------------------//
    private function _long2short($link1) {
        $link1 = trim($link1, '?');
        $ary = explode('&', $link1);
        $link = '';
        if(is_array($ary) && count($ary)>1){
            foreach($ary as $var) {
                $varData = explode('=', $var);
                if(count($varData)>1){
                    $key = $varData[0];
                    $value = $varData[1]; 
                    if(isset($this->link_types[$key])){
                        $value = $this->_applayVarType($value, $this->link_types[$key]);
                        $link .= $value.'/';
                    }
                }else{
                    return $link1; 
                }
            }
            return rtrim($link, '/');
        }
        return $link1;
    }
    //------------------------------------------------------------------//
    // Secure variable type.
    private function _applayVarType($value, $type) { 
        switch($type) {
            // You can add any security function you want.
            case 'int': $value = intval($value);                            break;
            case 'chr': $value = strlen($value)==1 ? $value : $value[0];    break;
        }
        return $value;
    }
    //------------------------------------------------------------------//
    function exclusionPath($path, $remove=null){
        $this->exclusion_path = $path;//str_replace($remove, '', $path);
        $this->remove_from_path = $remove;
    }
    //------------------------------------------------------------------//
    //------------------------------------------------------------------//
    // Main function for end-user, It's used to convert URL format
    function setURL($url, $type=0, $force=null){

        $parse = parse_url($url);

        if( isset($parse['host']) || $force){
            $scheme = isset($parse['scheme']) ? $parse['scheme'].'//' : '';
            $host     = isset($parse['host']) ? $parse['host'] : '';
            $path     = isset($parse['path']) ? $parse['path'] : '';
            $query     = isset($parse['query']) ? $parse['query'] : '';

            if(@$parse['host']==$_SERVER['HTTP_HOST'] || $force){
                if( $query ){
                    // long to short
                    $path = str_replace($this->exclusion_path, '', $path);
                    $url = $scheme.$host.$path
                        . str_replace($this->remove_from_path, '/', $this->exclusion_path)
                        . $this->_set($query, $type);
                    
                }elseif( $path  ){
                    // short to long
                    $path = str_replace($this->exclusion_path, '', $path);
                    $url = $scheme.$host.'/'
                    .$this->exclusion_path
                    .$this->_set($path, $type);
                    
                }
                $this->exclusion_path = null;
                $this->remove_from_path = null;
            }
        
        }else{
            trigger_error("Wrong URL Format!");
        
        }
        return $url;
        
    }
    //------------------------------------------------------------------//
} 
?>

استخدام الفئة


<?php
 $link = new CleanURL();

// Define parameters types
$link->define("
    int page;
    str cat;
    str sub;
    int id;
    chr k;
");

$url = 'http://localhost/1z/news/details/12/y';
echo '<hr><b>Convert short to long:</b>';
echo '<br /><b>Source:</b> '. $url .'<br /><b>Result:</b> ';
echo $link->setURL($url, CleanURL::LONG);
//------------------------------------------------------------------------

$url = 'http://localhost/?page=1&cat=news&sub=details&id=12code&k=false';
echo '<hr><b>Convert long to short:</b>';
echo '<br /><b>Source:</b> '. $url .'<br /><b>Result:</b> ';
echo $link->setURL($url, CleanURL::SHORT,  true);
//------------------------------------------------------------------------

$link->exclusionPath( 'forum/index.php');
$url = 'http://localhost/forum/index.php/1z/news/details/12/y';
echo '<hr><b>Convert short to long</b> [Use function "exclusionPath()"]: ';
echo '<br /><b>Source:</b> '. $url .'<br /><b>Result:</b> ';
echo $link->setURL($url, CleanURL::LONG);
//------------------------------------------------------------------------

$link->exclusionPath( 'index.php' , '.php');
$url = 'http://localhost/forum/index.php?page=1&cat=news&sub=details&id=12code&k=false';
echo '<hr><b>Convert long to short:</b> [Use function "exclusionPath()"]: ';
echo '<br /><b>Source</b>: '. $url .'<br /><b>Result:</b> ';
echo $link->setURL($url, CleanURL::SHORT);
//------------------------------------------------------------------------

$url = 'http://localhost/1/news/details/12/y';
echo '<hr><b>Convert short to long</b> [Use function "setType()"]: ';
echo '<br /><b>Source:</b> '. $url .'<br /><b>Result:</b> ';
$link->setType(CleanURL::LONG);
echo $link->setURL($url);
//------------------------------------------------------------------------

$url = 'http://othersite.com/any-query';
echo '<hr><b>Convert other site url</b> (Doesn\'t convert): ';
echo '<br /><b>Source</b>: '. $url .'<br /><b>Result:</b> ';
echo $link->setURL($url, CleanURL::LONG);


$url = 'http://othersite.com/forum/?page=1&cat=news&sub=details&id=12code&k=false';
echo '<hr><b>Convert other site url:</b> [Use "force" to convert]: ';
echo '<br /><b>Source</b>: '. $url .'<br /><b>Result:</b> ';
echo $link->setURL($url, CleanURL::SHORT,  true);  
?>
 في حالة وجود خطأ يرجى المشاركة وإيضاح الخطأ ليتم تلافيه، يسعدني قيامكم بتعديل اخطاء الكلاس..

الخميس، 11 أبريل 2013

التحميل الزائد الحقيقي real overload

يبدو أنه لن يهدأ لي بال حتى أحقق التحميل الزائد للغة php بطريقة أكثر وأكثر شبها ببقية اللغات البرمجية..

ستتمكن باستخدام الكلاس overloadable الاصدار v3.1 من استدعاء الدوال بالشكل:

$t->foo();

$t->foo('a');

$t->foo('a', 'b');

$t->foo('a', 2);

$t->foo('s', 2, 9);

$t->foo( array(4,5,6,7) );


كود كلاس overloadable :

/*******************************
 * author  :  hishamdalal@gmail.com 
 * version : 3.1
 * date    : 2013-04-11
 *****************************/

class overloadable
{
 protected $fname = null;
 protected $fargs = array();
 
 //--------------------------------------------------//
 function set($obj, $fname, $args){
  $n = ''; 
  $type = $this->getType($args); 
  $n  = "\$o = new $obj();\n";
  $n .= "if(method_exists(\$o, '$fname"."_$type')){\n";
  $n .= "\t\$r = \$o->$fname"."_$type(". $this->getArgsName($args) .");\n";
  $n .= "}else{\n\t\$r = null;\n";
  $n .= "\ttrigger_error('function ".$fname."_".$type." is not exist!');\n}";
  eval("\$r = $n;");
  return $r;
 }
 //--------------------------------------------------//
 function getType($args) {
  $argType = array();
  foreach($args as $i=>$val) {
   $argType[$i][] = $this->getSuffix($val, $i) ;
  }
  $s = '';
  if(is_array($argType)){
   foreach($argType as $type){
    $s  .= implode('', $type);
   }
   return $s;
  }
  return implode('', $argType);
 } 
 //--------------------------------------------------//
 function getSuffix($byValarg, $i) {
   if( is_numeric($byValarg) ) {
    $type = 'N'; 
    $this->fargs['N'.$i] = $byValarg;
   } elseif( is_array($byValarg) ) {
    $type = 'A';
    $this->fargs['A'.$i] = $byValarg;
   } elseif( is_object($byValarg) ) {
    $type = 'O'; 
    $this->fargs['O'.$i] = $byValarg;
   } elseif( is_resource($byValarg) ) {
    $type = 'R'; 
    $this->fargs['R'.$i] = $byValarg;
   } else {
    $type = 'S'; 
    $this->fargs['S'.$i] = $byValarg;
   } 
   return $type;
 }
 //--------------------------------------------------//
 function getArgsName($args){
  $r = array();
  $ary = array_keys($this->fargs);
  foreach( $ary as $k=>$v){
   $r[]='$this->fargs["'.$v.'"]';
  }
  return implode(", ", $r);
 }
 //--------------------------------------------------// 
 function __call($name, $args){
  $this->fargs = array();
  return $this->set(get_class($this), $name, $args);
 }
 //--------------------------------------------------// 
}

يمكنك الأن بسهولة استخدامه من خلال القيام بالوراثة منه إلى أي كلاس تريد أن تضيف امكانية التحميل الزائد اليه.. مثال لعمل كلاس يقوم بوراثة overloadable ولاحظ كيف تم بناء الدوال بنفس الاسم مع زيادة _ ثم أول حرف من نوع بيانات البراميترات المرسلة:

class test2 extends overloadable {
 function foo_(){
  echo 'foo - no args';
 }
 function foo_S($s){
  echo "foo - one string $s";
 }
 function foo_SS($s1, $s2){
  echo "foo - tow strings $s1, $s2";
 } 
 function foo_SN($s, $n){
  echo "foo - string and number $s, $n";
 }
 function foo_A($ary){
  print_r($ary);
 }
 function foo_AA($ary1, $ary2){
  if(is_array($ary1) && is_array($ary2)){
   echo "foo - tow arrays";
  }else{echo 0;}
 } 
 function foo_O($obj){
  echo "foo - ";
  print_r($obj);
 }
 function hi(){
  echo "hi - welcome!";
 }
}

لاحظ كيف تم بناء الدوال: فالدالة : foo_() لا تحتوي أي باراميتر والدالة foo_S($s) تحتوي متغير نص وهكذا تبني أي دالة ، لكن عند الاستدعاء يجب كتابة اسم الدالة دون شرطة أو رموز فتكتب فقط foo() أو foo('a') كالتالي:

echo '<pre>';
$t = new test2();

echo '< br />foo_: ';
print_r( $t->foo() );

echo '< br />foo_s: ';
print_r( $t->foo('a') );

echo '< br />foo_ss: ';
print_r( $t->foo('a', 'b') );

echo '< br />foo_sn: ';
print_r( $t->foo('a', 2) );

echo '< br />foo_snn: ';
print_r( $t->foo('s', 2, 9) );

echo '< br />foo_a: ';
print_r( $t->foo(array(4,5,6,7)) );

echo '< br />foo_aa: ';
print_r( $t->foo( array(5,6,7), array(8,9,10) ) );

echo '< br />foo_o: ';
print_r( $t->foo($t) );

echo '< br />hi: ';
print_r( $t->hi() );

الأربعاء، 10 أبريل 2013

Class overloadable to make ability for overloading in php كلاس لتمكين التحميل الزائد في php

بعد طول انقطاع أعود للتدوين.. مرحبا بكم :) أبدأ على بركة الله تدوينة جديدة: تحدثت في مقالة سابقة Overloading in php just like C Sharp عن كيفية عمل overload للغة php تشبه الى حد ما خاصية overload في c// الآن اقدم طريقة أحدث، وكود الكلاس كما يلي:

class overloadable 
{ 
 protected $args = array();
 private $argType = array();
 private $argArry = array();
 private $constructArgsAry = array();
 private $method;
 private $className ='';
 
 function setConstructArgs($args) {
  $this->constructArgsAry = $args;
 }
 //--------------------------------------------------//
 function getMethod($className, $method, $args) {
  $this->className = $className;
  
  $this->args = $args;
  $type = $this->getTypes($args);
  
  $method = $method.'_'.$type;
  $this->method = $method; 
  
  return $this->callFunc();
 }
 //--------------------------------------------------//
 function getTypes($args) {
  foreach($args as $i=>$val) {
   $this->argType[$i] = $this->getType($val) ;
  }
  return implode('', $this->argType);
 }
 //--------------------------------------------------//
 function getType($byValarg) {
   if( is_numeric($byValarg) ) {
    $type = 'N'; //'numeric';
   } elseif( is_array($byValarg) ) {
    $type = 'A'; //'array';
   } elseif( is_object($byValarg) ) {
    $type = 'O'; //'object';
   } elseif( is_resource($byValarg) ) {
    $type = 'R'; //'resource';
   } else {
    $type = 'S'; //'string';
   } 
   return $type;
 }
 //--------------------------------------------------//
 function callFunc() {
  $className = $this->className;
  $method = $this->method;
  
  $constr_argsStringKeys='';

  $num_args = count($this->args);
  $argsAry = array();
  if($num_args>0){
   
   for($i=0; $i<$num_args; $i++) {
    $argsAry['$arg_'.$i] = $this->args[$i];
    eval("\$arg_$i = \$this->args[$i];");
   }
   $argsStringKeys = implode(', ', array_keys($argsAry));

   $func = create_function($argsStringKeys, 
      '$d = new '.$className.'('
      . $constr_argsStringKeys .'); return $d->'
      . $method.'('.$argsStringKeys.');');
   
   eval("\$f = \$func($argsStringKeys);"); 
   return $f;
  } 
 }
}

طريقة الاستخدام : يجب أن تقوم بعمل وراثة من الكلاس overloadable يجب اضافة كود معين للدالة التي لا تحتوي على أي براميتر. ثم اضافة دوال أخرى بنفس الاسم ولكن يضاف في نهاية اسم الدالة شرطة مائلة _ ثم أول حرف من نوع المتغير فمثلا: الدالة hi_s تعني أن هذه الدالة لها براميتر واحد نصي الدالة hi_sa تعني ان هذه الدالة لها براميترين واحد نصي والثاني مصفوفة. مثلاً يتم بناء كلاس وليكن اسمه myClass:

class myClass extends overloadable 
{
 function hi() {
  // important to work other methods
  $r = parent::getMethod(__CLASS__, __FUNCTION__, func_get_args());
  if($r){ return $r; }
  // code for method hi();
  return 'hi!';
 }
 function hi_s($name){
  return "Hi $name";
 }
 function hi_ss($var1, $var2){
  return "Hi $var1 $var2";
 }
 function hi_sa($name, $ary){
  $r = $name.' have ';
  foreach($ary as $thing){
   $r .= "$thing and ";
  }
  return rtrim($r, 'and ') .'.';
 }
 
 function hi_aa($ary1, $ary2){
  return 'Ary1: '. print_r($ary1, 1).' < br />ARY2:'. print_r($ary2, 1);
 }
 
 function wins(){
  $r = parent::getMethod(__CLASS__, __FUNCTION__, func_get_args());
  if($r){ return $r; }
  return 'You are the winner!';
 }
 
 function wins_sn($wining, $cash){
  return $wining.' wins '. $cash .'$';
 }
}

مثال على استخدام الكلاس myClass:

$o = new myClass();

echo '<pre>';
print_r( $o->hi() );
echo '< br />';
print_r( $o->hi('saleem', array('a job', 'a car', 'a house') ) );
echo '< br />';
print_r( $o->hi('Hishahm', 'Dalal') );
echo '< br />';
print_r( $o->hi(array(1,2), array('a','b') ) );
echo '< br />';
print_r( $o->wins('Hisahm', 1000) );
echo '< br />';
print_r( $o->wins() );

لتحميل المثال كاملا انقر هنا

 
Design by Free WordPress Themes | Bloggerized by Lasantha - Premium Blogger Themes | Blogger Templates | تعريب وتطوير : قوالب بلوجر معربة