1 (edited by m[e]ntor 2008-02-08 8:25:01 AM)

Topic: [alpha] Dynamic registering Methods and Classes

Hi,

yesterday i had a session with CtC about how we can register Classes and/or Functions dynamicly.

The sense behind that is, how we can call an ajax-function, which includes another php-class, and that class provides new ajax-functions.

After a little time we get a first solution :

[code php]
index.php
<?php
ini_set("display_errors",1);
error_reporting(E_ALL ^E_NOTICE);
session_start();
require_once( 'class1.php');
$core = './xajax/xajax_core';
require_once( $core . '/xajax.inc.php' );

$xajax = new xajax();

$xajax->configure('javascript URI', 'xajax/');


$class1 = new class1($xajax);

$configuration = $_SESSION['object_loader_configuration'];
if ( is_array( $configuration ) )
{
    //$session = print_r( $_SESSION );
    //echo $session;
   
foreach ($configuration as $className => $classConfiguration)
{
    foreach ($classConfiguration as $includeFile => $methods)
    {
        require $includeFile;
        $class = new $className( $xajax );
        foreach ($methods as $method)
        {
            $xajax->register(XAJAX_FUNCTION, array(&$class, $method));
        }
    }
}
}


$xajax->processRequest();
?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/2000/REC-xhtml1-20 … tional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Dynamic Classes </title>
<?php $xajax->printJavascript(); ?>
</head>
<body>
    <h1>classTesT</h1>
    <?=$class1->proceed()?>
    <?=$session?>
</body>
</html>

[/code]

[code php]
class1.php
<?php

class class1
{
    public function __construct( $xajax )
    {
        $this->xajax = $xajax;
       
        $xajax->registerFunction(array('ajax_class1_test', $this, 'ajax_class1_test' ) );       
        $xajax->registerFunction(array('ajax_class1_test2', $this, 'ajax_class1_test2' ) );       
    }
   
    public function proceed()
    {
        return '<a href="javascript:void(0);" onclick="xajax_ajax_class1_test2()">removeme</a><br><a href="javascript:void(0);" onclick="xajax_ajax_class1_test()">test</a><div id="test"></div>';
    }
   
    public function ajax_class1_test()
    {
        $response = new xajaxResponse();
       
        require_once( 'class2.php');
       
        $class2 = new class2($this->xajax);
       
        $configuration = array();
        if (isset($_SESSION['object_loader_configuration']))
        {
            $configuration = $_SESSION['object_loader_configuration'];
        }
       
        $configuration['class2'] = array(
            'class2.php' => array(
                 'ajax_class2_test'
                )
            );
       
        $_SESSION['object_loader_configuration'] = $configuration;       
       
       
        $response->assign('test', 'innerHTML', $class2->proceed() );
       
        return $response;
    }
   
    public function ajax_class1_test2()
    {
        $response = new xajaxResponse();
       
        $configuration = array();
        if (isset($_SESSION['object_loader_configuration']))
        {
            $configuration = $_SESSION['object_loader_configuration'];
           
            if ( array_key_exists( 'class2', $configuration ) )
            {
                unset( $configuration['class2'] );
            }
        }
       
        $_SESSION['object_loader_configuration'] = $configuration;       
       
       
        $response->append('test', 'innerHTML', 'but it will not work' );
       
        return $response;
    }
}

?>
[/code]

[code php]
class2.php
<?php

class class2
{
    public function __construct( $xajax )
    {
    }
   
    public function proceed()
    {
        return '<a href="javascript:void(0);" onclick="xajax.request( { xjxfun: \'ajax_class2_test\' }, { parameters: arguments } );">test</a>';
    }
   
    public function ajax_class2_test()
    {
        $response = new xajaxResponse();
       
        $response->alert('Hello World');
       
        return $response;
    }
}

?>
[/code]

maybe we  or CtC will write a plugin for that.

Greets

Oliver

2 (edited by edrobinson 2010-01-26 7:21:04 PM)

Re: [alpha] Dynamic registering Methods and Classes

I have been trying to do a one page xajax site wherein the "front page" contains an area that receives new page content and is able to call xajax aware functions in any .php file with classes defined. i.e:

onclick="xajax_caller('classname','methodname','filename',params)"

I found a class that makes possible calling unregistered functions here:

http://my.opera.com/superlolek/blog/200 … nt17051371

It allows calling a class method with or without parameters and returning an xajaxResponse object.

I have taken it a step further and made it possible to recognize a parameter as a php file containing the class of interest, including it and calling methods withing it.

<?php
class myAjaxCaller {
/**
 * Use to execute xajax methods without registering them. 
 * accept at least 2 params : 1- class name, 2- method name  
 *
 * @author lolek
 * @copyrights lolek
 * @website http://my.opera.com/superlolek/
 * @date 2009-07-02
 * @param void
 * @return xajaxResponse
 * 1/25/10 - Ed robinson modifications
 * The third parameter may be an include file i.e. "myclassfile" without the
 * .php extension.
 * If 3 or more params we now try to include the file if it exists.
 * When calling the user function we pass param array depending on 
 * whether we found an include. 
 */
public function callUser() {
    $r = new xajaxResponse(); //create xajax Response object
    try {
        $fArgs = func_num_args(); //get argument count....
        if($fArgs <2) //there should be at least 2 args, 1 is the class name, 2 is the method name
        {
            throw new Exception ('Insuffcient parameters count');
        }
        else
        {
            $fNumArgs = $fArgs; //Sace for below Ed
            $fArgs = func_get_args();
            $cName = $fArgs[0]; //as above - class name
            $mName = $fArgs[1]; //method name (method should be of access type public!! 
                                //and return  xajaxResponse object!!
            //Ed's changes 1/26/10
            $bIncluded = false;
            if($fNumArgs >= 3) //args[2] may be the include file or a param
            {
              $fName = $fArgs[2].'.php';
              if (file_exists($fName))
              { 
                include($fName);
                $bIncluded = true;
              }
            }
            if (class_exists($cName))
            {
              $reflectObj = new ReflectionClass($cName); //create reflection object
              $cObj = $reflectObj->newInstance(); 
              if(!method_exists($cObj,$mName)) //if method doesn't exists, throw an error
              {
                 throw new Exception('unable to invoke specified method - doesn\'t exist');
              }
              if($fNumArgs==2) //if there are only 2 args, then the method will be invoked without
              {             // without any parameters
                  $r->loadCommands(call_user_func(array($cObj,$mName)));
              }
              else //if there are more than 2 parameters, then method will be invoked 
              {    //with  arguments specified while calling callUser     
                 if ($bIncluded === true)//Was an include loaded?
                  $r->loadCommands(call_user_func_array(array($cObj,$mName),array_slice($fArgs,3)));
                 else
                  $r->loadCommands(call_user_func_array(array($cObj,$mName),array_slice($fArgs,2)));
              }
            }
            else
            {
              throw new Exception('Class not found');
            }
        }

    } catch (Exception $e) {
        //catch exception and show error message 
        $r->alert($e->getMessage());
    }
    return $r; //return xajaxresponse object
}
} //End class...
?>

Sample simple class (testing.php) to be included:

<?php
class testClass {
  public function testIt()
  {
    $r = new xajaxResponse();
    $numargs = func_num_args();
    if ($numargs == 0)
    $r->alert("No arguments passed.");
    else
      $r->alert(func_get_arg(0));
    return $r;
  }
}
?>

Sample xajax page using the caller class:

<?php
require_once("commons.php");
require_once("myajaxcaller.php");
$ajxCall = new myajaxCaller();
$xajax->configure('debug',true);
$xajax->registerFunction(Array('callUser',$ajxCall,'callUser'));
$xajax->processRequest();

?>
<html>
<head>
<?php $xajax->printJavascript(); ?>
</head>
<body>
<input type="button" value="Click" onclick="xajax_callUser('testClass','testit');"/>
<input type="button" value="Click load class file" onclick="xajax_callUser('testClass','testit','testing');"/>
<input type="button" value="Click losd pass param" onclick="xajax_callUser('testClass','testit','testing','Hello World');"/>
</body>
</html>

This seems somewhat like what this thread was started about...

If not slap me smile

Using this should make possible the "single page" site - film at eleven.

Comments?

ED

If you ever stop learning you may as well dig a hole, crawl in and pull the top over yourself.

Re: [alpha] Dynamic registering Methods and Classes

Why not have a peak at smarty. They use a dynamic loader for at least in the smarty 3 code now.

And I still have this request for specifying the methods to use.
I use class inheritance, so it is not wanted to get a xajax method in javascript for every class method in php.
This feature i implemented this for quite some time now in my own repository, and it won't be that difficult to submit them to the xajax repos.

Re: [alpha] Dynamic registering Methods and Classes

Hi Doc,


I do use Smarty and really like it. What I am coming to with a one pager is to use smarty's fetch() function and assigning the result to a div on the page. I may need to have a look Smarty 3.

The ONLY xajax registered function is callUser() shown in the class above. It gets called from the browser passing the class name, function to call withing the class, class file name and optional arguments. So far, so good.

Back button handling is a bit of an inconvenience. May have to use a "stack" in the session variables...

Ed

If you ever stop learning you may as well dig a hole, crawl in and pull the top over yourself.

Re: [alpha] Dynamic registering Methods and Classes

Doc,

I have been reading in the Smarty forums and trying to understand "dynamic loading" but still don't get it.

Can you expand on it a bit please?

Ed

If you ever stop learning you may as well dig a hole, crawl in and pull the top over yourself.

Re: [alpha] Dynamic registering Methods and Classes

i think it basicly comes down to this : http://www.smarty.net/manual/en/plugins … ntions.php

But i think, my way is beter, describe the method you want to use.
My idea is also, to minimize the javascript more, by using this dynamic implementation. Just look out for security leaks wink