Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Sun, Feb 2, 9:47 AM

in-portal

Index: trunk/core/kernel/event_manager.php
===================================================================
--- trunk/core/kernel/event_manager.php (nonexistent)
+++ trunk/core/kernel/event_manager.php (revision 932)
@@ -0,0 +1,192 @@
+<?php
+
+ define('hBEFORE',1);
+ define('hAFTER',2);
+
+ class kEventManager extends kDBBase {
+
+ /**
+ * Build events registred for
+ * pseudo classes. key - pseudo class
+ * value - event name
+ *
+ * @var Array
+ * @access private
+ */
+ var $buildEvents=Array();
+
+ /**
+ * Holds before hooks
+ * key - prefix.event (to link to)
+ * value - hooked event info
+ *
+ * @var Array
+ * @access private
+ */
+ var $beforeHooks=Array();
+
+ /**
+ * Holds after hooks
+ * key - prefix.event (to link to)
+ * value - hooked event info
+ *
+ * @var Array
+ * @access private
+ */
+ var $afterHooks=Array();
+
+ function registerBuildEvent($pseudo_class,$build_event_name)
+ {
+ $this->buildEvents[$pseudo_class]=$build_event_name;
+ }
+
+ /**
+ * Returns build event by pseudo class
+ * name if any defined in config
+ *
+ * @param string $pseudo_class
+ * @return kEvent
+ * @access public
+ */
+ function &getBuildEvent($pseudo_class)
+ {
+ if( !isset($this->buildEvents[$pseudo_class]) ) return false;
+
+ $event = new kEvent();
+ $event->Name=$this->buildEvents[$pseudo_class];
+ $event->MasterEvent=null;
+ return $event;
+ }
+
+ /**
+ * Allows to process any type of event
+ *
+ * @param kEvent $event
+ * @access public
+ */
+ function HandleEvent(&$event)
+ {
+ $event_handler =& $this->Application->recallObject($event->Prefix.'_EventHandler');
+ $event_handler->processEvent(&$event);
+ }
+
+ function getTemplateName($querystring_template)
+ {
+ $t_from_post=$this->Application->GetVar('t');
+ $t=$t_from_post?$t_from_post:$querystring_template;
+ return $t;
+ }
+
+ function ProcessRequest()
+ {
+ // env=SID:TEMPLATE:m-1-1-1-1:l0-0-0:n-0-0-0:bb-0-0-1-1-1-0
+
+ // 1. process QueryString
+ $env_var =& $this->Application->GetVar(ENV_VAR_NAME);
+ $query_maps=Array();
+
+ if($env_var)
+ {
+ $parts=explode(':',$env_var);
+
+ // Save Session ID
+ $sid=array_shift($parts);
+ if($sid) $this->Application->SetVar('sid',$sid);
+
+ // Save Template Name
+ $t=$this->getTemplateName( array_shift($parts) );
+ if(!$t) $t='index';
+ $this->Application->SetVar('t',$t);
+
+ if($parts)
+ {
+ foreach($parts as $mixed_part)
+ {
+ $mixed_part=explode('-',$mixed_part);
+ $prefix_special=array_shift($mixed_part); // l.pick, l
+ list($prefix)=explode('.',$prefix_special);
+
+ $query_maps[$prefix_special]=$this->Application->getUnitOption($prefix,'QueryString');
+ foreach($query_maps[$prefix_special] as $index => $var_name)
+ {
+ // l_id, l_page, l_bla-bla-bla
+ $this->Application->SetVar($prefix_special.'_'.$var_name,$mixed_part[$index-1]);
+ }
+ }
+ }
+ }
+ else
+ {
+ $t=$this->getTemplateName('index');
+ $this->Application->SetVar('t',$t);
+ }
+
+ // 1. get events from $_POST
+ $events=$this->Application->GetVar('events');
+ if($events===false) $events=Array();
+ // 2. if nothing there, then try to find them in $_GET
+ if($query_maps && !$events)
+ {
+ // if we got $_GET type submit (links, not javascript)
+ foreach($query_maps as $prefix_special => $query_map)
+ {
+ $query_map=array_flip($query_map);
+ if(isset($query_map['event']))
+ {
+ $events[$prefix_special]=$this->Application->GetVar($prefix_special.'_event');
+ }
+ }
+ }
+
+ //print_pre($events);
+ $t=$this->Application->GetVar('t');
+ foreach($events as $prefix_special => $event_name)
+ {
+ if(!$event_name) continue;
+ $event = new kEvent();
+ $event->Name=$event_name;
+ $event->Prefix_Special=$prefix_special;
+
+ $prefix_special=explode('.',$prefix_special);
+ $event->Prefix=$prefix_special[0];
+ $event->Special=isset($prefix_special[1])?$prefix_special[1]:'';
+
+ $event->redirect=$this->Application->RecallVar('redirect_to');
+ $this->HandleEvent(&$event);
+ }
+ }
+
+ function registerHook($hookto_unit, $hookto_event_name, $mode, $do_unit, $do_event_name)
+ {
+
+
+
+
+ }
+
+ function processHooks(&$event, $mode)
+ {
+
+
+
+
+ }
+
+ /**
+ * Set's new event for $prefix_special
+ * passed
+ *
+ * @param string $prefix_special
+ * @param string $event_name
+ * @access public
+ */
+ function setEvent($prefix_special,$event_name)
+ {
+ $actions =& $this->Application->recallObject('kActions');
+ $actions->Set('events['.$prefix_special.']',$event_name);
+ }
+
+ }
+
+
+?>
\ No newline at end of file
Property changes on: trunk/core/kernel/event_manager.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/core/kernel/processors/tag_processor.php
===================================================================
--- trunk/core/kernel/processors/tag_processor.php (nonexistent)
+++ trunk/core/kernel/processors/tag_processor.php (revision 932)
@@ -0,0 +1,74 @@
+<?php
+
+ class TagProcessor extends kBase {
+
+ /**
+ * Processes tag
+ *
+ * @param Tag $tag
+ * @return string
+ * @access public
+ */
+ function ProcessTag(&$tag)
+ {
+ $Method=$tag->Tag;
+ if(method_exists($this, $Method))
+ {
+ //echo htmlspecialchars($tag->GetFullTag()).'<br>';
+ return $this->$Method($tag->NP);
+ }
+ else
+ {
+ $this->Application->trigerError('Tag Undefined:<br><b>'.$tag->RebuildTagData().'</b>');
+ return false;
+ }
+ }
+ }
+
+/*class ProcessorsPool {
+ var $Processors = Array();
+ var $Application;
+ var $Prefixes = Array();
+ var $S;
+
+ function ProcessorsPool()
+ {
+ $this->Application =& KernelApplication::Instance();
+ $this->S =& $this->Application->Session;
+ }
+
+ function RegisterPrefix($prefix, $path, $class)
+ {
+ // echo " RegisterPrefix $prefix, $path, $class <br>";
+ $prefix_item = Array(
+ 'path' => $path,
+ 'class' => $class
+ );
+ $this->Prefixes[$prefix] = $prefix_item;
+ }
+
+ function CreateProcessor($prefix, &$tag)
+ {
+ // echo " prefix : $prefix <br>";
+ if (!isset($this->Prefixes[$prefix]))
+ die ("<b>Filepath and ClassName for prefix $prefix not defined while processing ".htmlspecialchars($tag->GetFullTag())."!</b>");
+ include_once($this->Prefixes[$prefix]['path']);
+ $ClassName = $this->Prefixes[$prefix]['class'];
+ $a_processor =& new $ClassName($prefix);
+ $this->SetProcessor($prefix, $a_processor);
+ }
+
+ function SetProcessor($prefix, &$a_processor)
+ {
+ $this->Processors[$prefix] =& $a_processor;
+ }
+
+ function &GetProcessor($prefix, &$tag)
+ {
+ if (!isset($this->Processors[$prefix]))
+ $this->CreateProcessor($prefix, $tag);
+ return $this->Processors[$prefix];
+ }
+}*/
+
+?>
\ No newline at end of file
Property changes on: trunk/core/kernel/processors/tag_processor.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/core/kernel/processors/main_processor.php
===================================================================
--- trunk/core/kernel/processors/main_processor.php (nonexistent)
+++ trunk/core/kernel/processors/main_processor.php (revision 932)
@@ -0,0 +1,459 @@
+<?php
+
+class MainProcessor extends TagProcessor {
+
+ function Init($prefix,$special)
+ {
+ parent::Init($prefix,$special);
+
+ $actions =& $this->Application->recallObject('kActions');
+ $actions->Set('t', $this->Application->GetVar('t'));
+ $actions->Set('sid', $this->Application->GetSID());
+ }
+
+ /**
+ * Used to handle calls where tag name
+ * match with existing php function name
+ *
+ * @param Tag $tag
+ * @return string
+ */
+ function ProcessTag(&$tag)
+ {
+ if ($tag->Tag=='include') $tag->Tag='MyInclude';
+ return parent::ProcessTag($tag);
+ }
+
+ function Base_Ref($params)
+ {
+ $templates_path = substr(THEMES_PATH,1);
+ return "<base href='".$this->Application->BaseURL().$templates_path."/'>";
+ }
+
+ function Base_URL($params)
+ {
+ $templates_path = substr(THEMES_PATH,1);
+ return $this->Application->BaseURL().$templates_path;
+ }
+
+ function Base($params)
+ {
+ return $this->Application->BaseURL().$params['add'];
+ }
+
+ /**
+ * Returns sid of current object
+ *
+ * @param Array $params
+ * @return int
+ * @todo Is really called ?
+ */
+ /*function Sid($params)
+ {
+ $session =& $this->Application->recallObject('Session');
+ return $session->GetId();
+ }*/
+
+ //NEEDS TEST
+ function T($params)
+ {
+ if(!isset($params['pass'])) $params['pass']='';
+ $t = (isset($params['t']) && $params['t']) ? $params['t'] : $this->Application->GetVar('t');
+ $this->Application->SetVar('t_pass',$params['pass']);
+ return $this->Application->HREF($t, isset($params['prefix']) ? $params['prefix'] : '');
+ }
+
+ // NEEDS TEST
+ function Config($params)
+ {
+ return $this->Application->ConfigOption($params['var']);
+ }
+
+ function Object($params)
+ {
+ $name = $params['name'];
+ $method = $params['method'];
+
+ $tmp =& $this->Application->recallObject($name);
+ if ($tmp != null) {
+ if (method_exists($tmp, $method))
+ return $tmp->$method($params);
+ else
+ echo "Method $method does not exist in object ".get_class($tmp)." named $name<br>";
+ }
+ else
+ echo "Object $name does not exist in the appliaction<br>";
+ }
+
+ function True($params)
+ {
+ return true;
+ }
+
+ function False($params)
+ {
+ return false;
+ }
+
+ function Param($params)
+ {
+ //$parser =& $this->Application->recallObject('TemplateParser');
+ $res = $this->Application->Parser->GetParam($params['name']);
+ if ($res === false) $res = '';
+ if (isset($params['plus']))
+ $res += $params['plus'];
+ return $res;
+ }
+
+ function Param_Equals($params)
+ {
+ //$parser =& $this->Application->recallObject('TemplateParser');
+ $name = $this->SelectParam($params, 'name,var,param');
+ $value = $params['value'];
+ return ($this->Application->Parser->GetParam($name) == $value);
+ }
+
+ /**
+ * Returns hidden field for template name
+ *
+ * @param Array $params
+ * @return string
+ * @todo Is really called ?
+ */
+ /*function Hidden_t($params)
+ {
+ return "<input type=hidden name='t' value='".$this->Application->GetVar('t')."'>";
+ }*/
+
+ /**
+ * Returns hidden field for SID
+ *
+ * @param Array $params
+ * @return string
+ * @todo Is really called ?
+ */
+ /*function Hidden_SID($params)
+ {
+ $session =& $this->Application->recallObject('Session');
+ return "<input type=hidden name='sid' value='".$session->GetID()."'>";
+ }*/
+
+ function PHP_Self($params)
+ {
+ return $HTTP_SERVER_VARS['PHP_SELF'];
+ }
+
+ function SelectParam($params, $possible_names)
+ {
+ if (!is_array($params)) return;
+ if (!is_array($possible_names))
+ $possible_names = explode(',', $possible_names);
+ foreach ($possible_names as $name) {
+ if (array_key_exists($name, $params)) return $params[$name];
+ }
+ return false;
+ }
+
+ function Recall($params)
+ {
+ $res = $this->Application->RecallVar($this->SelectParam($params, 'name,var,param'));
+ if ($res === false && isset($params['no_null']))
+ return '';
+ else
+ return $res;
+ }
+
+ function Store($params)
+ {
+ //echo"Store $params[name]<br>";
+ $name = $params['name'];
+ $value = $params['value'];
+ $this->Application->StoreVar($name,$value);
+ }
+
+ function Set($params)
+ {
+ foreach ($params as $param => $value) {
+ $this->Application->SetVar($param, $value);
+ }
+ }
+
+ function Inc($params)
+ {
+ $this->Application->SetVar($params['param'], $this->Application->GetVar($params['param']) + $params['by']);
+ }
+
+ function Get($params)
+ {
+ return $this->Application->GetVar($this->SelectParam($params, 'name,var,param'), EMPTY_ON_NULL);
+ }
+
+ function Config_Equals($params)
+ {
+ foreach ($params as $name => $val) {
+ if (in_array($name, Array( 'prefix', 'function'))) continue;
+ return $this->Application->ConfigOption($name) == $val;
+ }
+ return false;
+ }
+
+ function DumpSystemInfo($params)
+ {
+ $actions =& $this->Application->recallObject('kActions');
+ $actions->Set('t', $this->Application->GetVar('t') );
+
+ $params = $actions->GetParams();
+ $o = '';
+ foreach ($params AS $name => $val) {
+ $o .= "<input type='hidden' name='$name' id='$name' value='$val'>\n";
+ }
+ return $o;
+ }
+
+ function Odd_Even($params)
+ {
+ $odd = $params['odd'];
+ $even = $params['even'];
+
+ if ($this->Session->GetProperty('odd_even') == 'even') {
+ $this->Session->SetProperty('odd_even', 'odd');
+ return $even;
+ }
+ else {
+ $this->Session->SetProperty('odd_even', 'even');
+ return $odd;
+ }
+ }
+
+ function Phrase($params)
+ {
+ // m:phrase name="phrase_name" default="Tr-alala" updated="2004-01-29 12:49"
+ if (array_key_exists('default', $params)) return $params['default']; //backward compatibility
+ return $this->Application->Phrase($this->SelectParam($params, 'label,name,title'));
+ }
+
+ // for tabs
+ function is_active($params)
+ {
+ // echo " is_active <br> ";
+ $test_templ = $params["templ"];
+ if (!$params['allow_empty']) {
+ $if_true = $params["true"] != '' ? $params["true"] : 1;
+ $if_false = $params["false"] != '' ? $params["false"] : 0;
+ }
+ else {
+ $if_true = $params["true"];
+ $if_false = $params["false"];
+ }
+
+ if ( eregi("^$test_templ", $this->Application->GetVar('t')))
+ return $if_true;
+ else
+ return $if_false;
+ }
+
+ function is_t_active($params)
+ {
+ return $this->is_active($params);
+ }
+
+ function Recall_Equals($params)
+ {
+ $name = $params['var'];
+ $value = $params['value'];
+ return ($this->Application->RecallVar($name) == $value);
+ }
+
+ function Get_Equals($params)
+ {
+ $name = $this->SelectParam($params, 'var,name,param');
+ $value = $params['value'];
+ if ($this->Application->GetVar($name) == $value) {
+ return 1;
+ }
+ }
+
+ function MyInclude($params)
+ {
+ $BlockParser =& $this->Application->Factory->makeClass('TemplateParser');
+ $BlockParser->SetParams($params);
+ $parser =& $this->Application->Parser;
+
+ $t = $params['t'];
+ $t = eregi_replace("\.tpl$", '', $t);
+
+ $templates_cache =& $this->Application->recallObject('TemplatesCache');
+
+ $res = $BlockParser->Parse( $templates_cache->GetTemplateBody($t) );
+
+ $this->Application->Parser =& $parser;
+ return $res;
+ }
+
+ function Kernel_Scripts($params)
+ {
+ return '<script type="text/javascript" src="'.PROTOCOL.SERVER_NAME.BASE_PATH.'/kernel3/js/grid.js"></script>';
+ }
+
+
+ function GetUserPermission($params)
+ {
+ // echo"GetUserPermission $params[name]";
+ if ($this->Application->RecallVar('user_type') == 1)
+ return 1;
+ else {
+ $perm_name = $params[name];
+ $aPermissions = unserialize($this->Application->RecallVar('user_permissions'));
+ if ($aPermissions)
+ return $aPermissions[$perm_name];
+ }
+ }
+
+ function t_url($params)
+ {
+ $url = $this->Application->HREF($this->Application->GetVar('t'));
+ return $url;
+ }
+
+ function AddParam($params)
+ {
+ $parser =& $this->Application->Parser; // recallObject('TemplateParser');
+ foreach ($params as $param => $value) {
+ $this->Application->SetVar($param, $value);
+ $parser->SetParam($param, $value);
+ $parser->AddParam('/\$'.$param.'/', $value);
+ }
+ }
+
+ function ParseToVar($params)
+ {
+ $var = $params['var'];
+ $tagdata = $params['tag'];
+ $parser =& $this->Application->Parser; //recallObject('TemplateParser');
+ $res = $this->Application->ProcessTag($tagdata);
+
+ $parser->SetParam($var, $res);
+ $parser->AddParam('/\$'.$var.'/', $res);
+ return '';
+ }
+
+ function TagNotEmpty($params)
+ {
+ $tagdata = $params['tag'];
+ $res = $this->Application->ProcessTag($tagdata);
+ return $res != '';
+ }
+
+ function TagEmpty($params)
+ {
+ return !$this->TagNotEmpty($params);
+ }
+
+ function ParseBlock($params)
+ {
+ $parser =& $this->Application->Parser; // recallObject('TemplateParser');
+ return $parser->ParseBlock($params);
+ }
+
+
+/*
+ function Login($params)
+ {
+ $user_prefix = 'users';
+ $this->parser->registerprefix($user_prefix);
+ $user_class = $this->parser->processors[$user_prefix]->item_class;
+
+ $candidate = new $user_class(NULL, $this->parser->processors[$user_prefix]);
+ //print_pre($this->Session->Property);
+
+ $special = array_shift($params);
+ //echo"$special<br>";
+ $candidate_id = $candidate->Login($this->Session->GetProperty('username'), $this->Session->GetProperty('password'), $special);
+
+ if ($candidate_id !== false) {
+ $this->Session->SetField('user_id', $candidate_id);
+ $this->Session->Update();
+ $this->Session->AfterLogin();
+
+ $this->parser->register_prefix('m');
+ $template = array_shift($params);
+ if ($template == '') $template = 'index';
+ $location = $this->parser->do_process_tag('m', 't', Array($template));
+ header("Location: $location");
+ exit;
+ }
+ elseif ($this->Session->GetProperty('username') != '') {
+ $this->Session->SetProperty('login_error', 'Incorrect username or password');
+ }
+ }
+ */
+
+}
+
+global $suite;
+if (isset($suite)) {
+ class TestMainProcessor extends TestCase {
+
+ function testParam_Equals()
+ {
+ global $application;
+ $mp =& new MainProcessor($application, 'm');
+ $mp->Application->Parser->SetParams( Array('test' => 1));
+ $this->assertTrue($mp->Param_Equals( Array('param' => 'test', 'value' => 1 )));
+ $this->assertFalse($mp->Param_Equals( Array('param' => 'test', 'value' => 2 )));
+ $this->assertFalse($mp->Param_Equals( Array('param' => 'test1', 'value' => 2 )));
+ }
+
+ function testParam()
+ {
+ global $application;
+ $mp =& new MainProcessor($application, 'm');
+ $mp->Application->Parser->SetParams( Array('test' => 2));
+ $this->assertEquals(2, $mp->Param( Array('name' => 'test')));
+ $this->assertEquals(5, $mp->Param( Array('name' => 'test', 'plus' => 3 )));
+ $this->assertEquals(1, $mp->Param( Array('name' => 'test', 'plus' => -1 )));
+ }
+
+ function testSetGet()
+ {
+ global $application;
+ $mp =& new MainProcessor($application, 'm');
+ $mp->Set( Array('test_var' => 7, 'another_var' => 'abc') );
+ $this->assertEquals(7, $mp->Get( Array('param' => 'test_var')));
+ $this->assertEquals('abc', $mp->Get( Array('param' => 'another_var')));
+ }
+
+ function testConfig()
+ {
+ global $application;
+ $mp =& new MainProcessor($application, 'm');
+ $application->Session->Config->SetOption('test_config_var', '1');
+ $this->assertEquals(true, $mp->Config_Equals( Array('test_config_var' => '1')));
+ }
+
+ function testOddEven()
+ {
+ global $application;
+ $mp =& new MainProcessor($application, 'm');;
+ $this->assertEquals('odd_value', $mp->Odd_Even(Array('odd' => 'odd_value', 'even' => 'even_value')));
+ $this->assertEquals('even_value', $mp->Odd_Even(Array('odd' => 'odd_value', 'even' => 'even_value')));
+ $this->assertEquals('odd_value', $mp->Odd_Even(Array('odd' => 'odd_value', 'even' => 'even_value')));
+ }
+
+ function testApplicationProcessTag()
+ {
+ global $application;
+ $this->assertEquals($application->GetSID(), $application->ProcessTag('m:sid'));
+ }
+
+ }
+ $suite->addTest(new TestSuite("TestMainProcessor"));
+
+
+
+
+
+
+}
+
+?>
\ No newline at end of file
Property changes on: trunk/core/kernel/processors/main_processor.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/core/kernel/session/session.php
===================================================================
--- trunk/core/kernel/session/session.php (nonexistent)
+++ trunk/core/kernel/session/session.php (revision 932)
@@ -0,0 +1,486 @@
+<?php
+
+/*
+
+The session works the following way:
+
+1. When a visitor loads a page from the site the script checks if cookies_on varibale has been passed to it as a cookie.
+2. If it has been passed, the script tries to get Session ID (SID) from the request:
+3. Depending on session mode the script is getting SID differently.
+ The following modes are available:
+
+ smAUTO - Automatic mode: if cookies are on at the client side, the script relays only on cookies and
+ ignore all other methods of passing SID.
+ If cookies are off at the client side, the script relays on SID passed through query string
+ and referal passed by the client. THIS METHOD IS NOT 100% SECURE, as long as attacker may
+ get SID and substitude referal to gain access to user' session. One of the faults of this method
+ is that the session is only created when the visitor clicks the first link on the site, so
+ there is NO session at the first load of the page. (Actually there is a session, but it gets lost
+ after the first click because we do not use SID in query string while we are not sure if we need it)
+
+ smCOOKIES_ONLY - Cookies only: in this mode the script relays solely on cookies passed from the browser
+ and ignores all other methods. In this mode there is no way to use sessions for clients
+ without cookies support or cookies support disabled. The cookies are stored with the
+ full domain name and path to base-directory of script installation.
+
+ smGET_ONLY - GET only: the script will not set any cookies and will use only SID passed in
+ query string using GET, it will also check referal. The script will set SID at the
+ first load of the page
+
+ smCOOKIES_AND_GET - Combined mode: the script will use both cookies and GET right from the start. If client has
+ cookies enabled, the script will check SID stored in cookie and passed in query string, and will
+ use this SID only if both cookie and query string matches. However if cookies are disabled on the
+ client side, the script will work the same way as in GET_ONLY mode.
+
+4. After the script has the SID it tries to laod it from the Storage (default is database)
+5. If such SID is found in the database, the script checks its expiration time. If session is not expired, it updates
+ its expiration, and resend the cookie (if applicable to session mode)
+6. Then the script loads all the data (session variables) pertaining to the SID.
+
+
+
+Usage:
+
+$session =& new Session(smAUTO); //smAUTO is default, you could just leave the brackets empty, or provide another mode
+
+$session->SetCookieDomain('my.domain.com');
+$session->SetCookiePath('/myscript');
+$session->SetCookieName('my_sid_cookie');
+$session->SetGETName('sid');
+$session->InitSession();
+
+...
+
+//link output:
+
+echo "<a href='index.php?'". ( $session->NeedQueryString() ? 'sid='.$session->SID : '' ) .">My Link</a>";
+
+*/
+
+//Implements session storage in the database
+class SessionStorage extends kDBBase {
+
+ var $Expiration;
+
+ var $OriginalData;
+
+ function SessionStorage()
+ {
+ parent::kDBBase();
+ $this->OriginalData = Array();
+ }
+
+ function StoreSession(&$session)
+ {
+ $query = sprintf( "INSERT INTO %sSessions (sid, expire) VALUES (%s, %s)",
+ TABLE_PREFIX,
+ $session->SID,
+ $session->Expiration);
+ $this->Conn->Query($query);
+ }
+
+ function DeleteSession(&$session)
+ {
+ $query = sprintf( "DELETE FROM %sSessions WHERE %s = %s",
+ TABLE_PREFIX,
+ 'sid',
+ $session->SID);
+ $this->Conn->Query($query);
+
+ $query = sprintf( "DELETE FROM %sSessionData WHERE %s = %s",
+ TABLE_PREFIX,
+ 'sid',
+ $session->SID);
+ $this->Conn->Query($query);
+
+ $this->OriginalData = Array();
+ }
+
+ function UpdateSession(&$session)
+ {
+ $query = sprintf( "UPDATE %sSessions SET expire = %s WHERE %s = %s",
+ TABLE_PREFIX,
+ $session->Expiration,
+ 'sid',
+ $session->SID);
+ $this->Conn->Query($query);
+ }
+
+ function LocateSession($sid)
+ {
+ $query = sprintf( "SELECT * FROM %sSessions WHERE %s = %s",
+ TABLE_PREFIX,
+ 'sid',
+ $sid);
+ $result = $this->Conn->GetRow($query);
+ if ($result === false || $result == NULL) {
+ return false;
+ }
+ $this->Expiration = $result['expire'];
+ return true;
+ }
+
+ function GetExpiration()
+ {
+ return $this->Expiration;
+ }
+
+ function LoadData(&$session)
+ {
+ $query = sprintf( "SELECT value,name FROM %sSessionData WHERE %s = %s",
+ TABLE_PREFIX,
+ 'sid',
+ $session->SID);
+ $this->OriginalData = $this->Conn->GetCol($query,'name');
+ return $this->OriginalData;
+ }
+
+ function SaveData(&$session)
+ {
+ $ses_data = $session->Data->GetParams();
+
+ $replace = '';
+ foreach ($ses_data as $key => $value) {
+ if (array_key_exists($key, $this->OriginalData) && $this->OriginalData[$key] == $value)
+ continue; //skip unchanged session data
+ else {
+ $replace .= sprintf("(%s, %s, %s),",
+ $session->SID,
+ $this->Conn->qstr($key),
+ $this->Conn->qstr($value));
+ }
+ }
+ $replace = rtrim($replace, ',');
+ if ($replace != '') {
+ $query = sprintf( 'REPLACE INTO %sSessionData (sid, name, value) VALUES %s',
+ TABLE_PREFIX,
+ $replace);
+ $this->Conn->Query($query);
+ }
+ }
+
+ function RemoveFromData(&$session, $var)
+ {
+ $query = sprintf( "DELETE FROM %sSessionData WHERE %s = %s AND %s = %s",
+ TABLE_PREFIX,
+ 'sid',
+ $session->SID,
+ 'name',
+ $this->Conn->qstr($var));
+ $this->Conn->Query($query);
+ unset($this->OriginalData[$var]);
+ }
+}
+
+define('smAUTO', 1);
+define('smCOOKIES_ONLY', 2);
+define('smGET_ONLY', 3);
+define('smCOOKIES_AND_GET', 4);
+
+class Session extends kBase {
+ var $Checkers;
+
+ var $Mode;
+ var $GETName = 'sid';
+
+ var $CookiesEnabled = true;
+ var $CookieName = 'sid';
+ var $CookieDomain;
+ var $CookiePath;
+ var $CookieSecure = 0;
+
+ var $SessionTimeout = 3600;
+ var $Expiration;
+
+ var $SID;
+
+ var $Storage;
+
+ var $CachedNeedQueryString = null;
+
+ var $Data;
+
+
+ function Session($mode = smAUTO)
+ {
+ parent::kBase();
+ $this->SetMode($mode);
+ }
+
+ function SetMode($mode)
+ {
+ $this->Mode = $mode;
+ }
+
+ function SetCookiePath($path)
+ {
+ $this->CookiePath = $path;
+ }
+
+ function SetCookieDomain($domain)
+ {
+ $this->CookieDomain = $domain;
+ }
+
+ function SetGETName($get_name)
+ {
+ $this->GETName = $get_name;
+ }
+
+ function SetCookieName($cookie_name)
+ {
+ $this->CookieName = $cookie_name;
+ }
+
+ function InitStorage()
+ {
+ $this->Storage =& new SessionStorage();
+ }
+
+ function Init($prefix,$special)
+ {
+ parent::Init($prefix,$special);
+
+ $this->CheckIfCookiesAreOn();
+ $this->Checkers = Array();
+ $this->InitStorage();
+ $this->Data =& new Params();
+ if ($this->Check()) {
+ $this->SID = $this->GetPassedSIDValue();
+ $this->Refresh();
+ $this->LoadData();
+ }
+ else {
+ $this->SetSession();
+ }
+ }
+
+ function CheckReferer()
+ {
+ $reg = '#^'.preg_quote(PROTOCOL.$this->CookieDomain.$this->CookiePath).'#';
+ return preg_match($reg, $_SERVER['HTTP_REFERER']);
+ }
+
+ function CheckIfCookiesAreOn()
+ {
+ if ($this->Mode == smGET_ONLY) {
+ //we don't need to bother checking if we would not use it
+ $this->CookiesEnabled = false;
+ return;
+ }
+ $http_query =& $this->Application->recallObject('HTTPQuery');
+ $cookies_on = $http_query->Cookie['cookies_on'];
+
+ if (!$cookies_on) {
+ //If referer is our server, but we don't have our cookies_on, it's definetly off
+ if ($this->CheckReferer()) {
+ $this->CookiesEnabled = false;
+ }
+ else {
+ //Otherwise we still suppose cookies are on, because may be it's the first time user visits the site
+ //So we send cookies on to get it next time (when referal will tell us if they are realy off
+ setcookie(
+ 'cookies_on',
+ 1,
+ time()+31104000, //one year should be enough
+ $this->CookiePath,
+ $this->CookieDomain,
+ $this->CookieSecure
+ );
+ }
+ }
+ else
+ $this->CookiesEnabled = true;
+ return $this->CookiesEnabled;
+ }
+
+ function Check()
+ {
+ // we should check referer if cookies are disabled, and in combined mode
+ // auto mode would detect cookies, get only mode would turn it off - so we would get here
+ // and we don't care about referal in cookies only mode
+ if ( $this->Mode != smCOOKIES_ONLY && (!$this->CookiesEnabled || $this->Mode == smCOOKIES_AND_GET) ) {
+ if (!$this->CheckReferer())
+ return false;
+ }
+
+ $sid = $this->GetPassedSIDValue();
+
+ if (empty($sid)) return false;
+
+ //try to load session by sid, if everything is fine
+ $result = $this->LoadSession($sid);
+
+ return $result;
+ }
+
+ function LoadSession($sid)
+ {
+ if ($this->Storage->LocateSession($sid)) {
+ //if we have session with such SID - get its expiration
+ $this->Expiration = $this->Storage->GetExpiration();
+
+ //If session has expired
+ if ($this->Expiration < time()) return false;
+
+ //Otherwise it's ok
+ return true;
+ }
+ else //fake or deleted due to expiration SID
+ return false;
+ }
+
+ function GetPassedSIDValue($use_cache = 1)
+ {
+ if (!empty($this->CachedSID) && $use_cache) return $this->CachedSID;
+ $http_query =& $this->Application->recallObject('HTTPQuery');
+
+ switch ($this->Mode) {
+ case smAUTO:
+ if ($this->CookiesEnabled) { //Cookies has the priority - we ignore everything else
+ $sid = $http_query->Cookie[$this->CookieName];
+ }
+ else {
+ $sid = $http_query->Get($this->GETName);
+ }
+ break;
+ case smCOOKIES_ONLY:
+ $sid = $http_query->Cookie[$this->CookieName];
+ break;
+ case smGET_ONLY:
+ $sid = $http_query->Get($this->GETName);
+ break;
+ case smCOOKIES_AND_GET:
+ $cookie_sid = $http_query->Cookie[$this->CookieName];
+ $get_sid = $http_query->Get($this->GETName);
+ //both sids should match if cookies are enabled
+ if (!$this->CookiesEnabled || ($cookie_sid == $get_sid))
+ $sid = $get_sid; //we use get here just in case cookies are disabled
+ else
+ $sid = '';
+ break;
+ }
+ $this->CachedSID = $sid;
+ return $this->CachedSID;
+ }
+
+ function GetID()
+ {
+ return $this->SID;
+ }
+
+ function GenerateSID()
+ {
+ list($usec, $sec) = explode(" ",microtime());
+
+ $sid_part_1 = substr($usec, 4, 4);
+ $sid_part_2 = mt_rand(1,9);
+ $sid_part_3 = substr($sec, 6, 4);
+ $digit_one = substr($sid_part_1, 0, 1);
+ if ($digit_one == 0) {
+ $digit_one = mt_rand(1,9);
+ $sid_part_1 = ereg_replace("^0","",$sid_part_1);
+ $sid_part_1=$digit_one.$sid_part_1;
+ }
+ $this->SID = $sid_part_1.$sid_part_2.$sid_part_3;
+ return $this->SID;
+ }
+
+ function SetSession()
+ {
+ $this->GenerateSID();
+ $this->Expiration = time() + $this->SessionTimeout;
+ switch ($this->Mode) {
+ case smAUTO:
+ if ($this->CookiesEnabled) {
+ $this->SetSessionCookie();
+ }
+ break;
+ case smGET_ONLY:
+ break;
+ case smCOOKIES_ONLY:
+ case smCOOKIES_AND_GET:
+ $this->SetSessionCookie();
+ break;
+ }
+ $this->Storage->StoreSession($this);
+ }
+
+ function SetSessionCookie()
+ {
+ setcookie(
+ $this->CookieName,
+ $this->SID,
+ $this->Expiration,
+ $this->CookiePath,
+ $this->CookieDomain,
+ $this->CookieSecure
+ );
+ }
+
+ function Refresh()
+ {
+ if ($this->CookiesEnabled) $this->SetSessionCookie(); //we need to refresh the cookie
+ $this->Storage->UpdateSession($this);
+ }
+
+ function Destroy()
+ {
+ $this->Storage->DeleteSession($this);
+ $this->Data =& new Params();
+ $this->SID = '';
+ if ($this->CookiesEnabled) $this->SetSessionCookie(); //will remove the cookie due to value (sid) is empty
+ $this->SetSession(); //will create a new session
+ }
+
+ function NeedQueryString($use_cache = 1)
+ {
+ if ($this->CachedNeedQueryString != null && $use_cache) return $this->CachedNeedQueryString;
+ switch ($this->Mode) {
+ case smAUTO:
+ if ($this->CookiesEnabled) {
+ $res = 0;
+ }
+ else {
+ $res = 1;
+ }
+ break;
+ case smCOOKIES_ONLY:
+ break;
+ case smGET_ONLY:
+ case smCOOKIES_AND_GET:
+ $res = 1;
+ break;
+ }
+ $this->CachedNeedQueryString = $res;
+ return $res;
+ }
+
+ function LoadData()
+ {
+ $this->Data->AddParams($this->Storage->LoadData($this));
+ }
+
+ function SaveData()
+ {
+ $this->Storage->SaveData($this);
+ }
+
+ function StoreVar($name, $value)
+ {
+ $this->Data->Set($name, $value);
+ }
+
+ function RecallVar($name)
+ {
+ return $this->Data->Get($name);
+ }
+
+ function RemoveVar($name)
+ {
+ $this->Storage->RemoveFromData($this, $name);
+ $this->Data->Remove($name);
+ }
+}
+
+?>
\ No newline at end of file
Property changes on: trunk/core/kernel/session/session.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/core/kernel/utility/iterator.php
===================================================================
--- trunk/core/kernel/utility/iterator.php (nonexistent)
+++ trunk/core/kernel/utility/iterator.php (revision 932)
@@ -0,0 +1,49 @@
+<?php
+
+class MyIterator {
+
+ var $Items;
+ var $Index;
+ var $Count;
+ var $CurrentIndex;
+
+ function MyIterator(&$items)
+ {
+ $this->Items =& $items;
+ $this->IndexItems();
+ $this->CurrentIndex = 0;
+ }
+
+ function IndexItems()
+ {
+ $i = 0;
+ foreach ($this->Items as $key => $item) {
+ $this->Index[$i] = $key; // ?????? $i++
+ $i++;
+ }
+ $this->Count = $i;
+ }
+
+ function HasMore()
+ {
+ return $this->CurrentIndex < $this->Count;
+ }
+
+ function GoNext()
+ {
+ $this->CurrentIndex++;
+ }
+
+ function &GetItem()
+ {
+ return $this->Items[$this->Index[$this->CurrentIndex]];
+ }
+
+ function GetKey()
+ {
+ return $this->Index[$this->CurrentIndex];
+ }
+
+}
+
+?>
\ No newline at end of file
Property changes on: trunk/core/kernel/utility/iterator.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/core/kernel/utility/utilities.php
===================================================================
--- trunk/core/kernel/utility/utilities.php (nonexistent)
+++ trunk/core/kernel/utility/utilities.php (revision 932)
@@ -0,0 +1,45 @@
+<?php
+
+class Utilites {
+ var $Application;
+
+ function Utilites()
+ {
+ $this->Application =& KernelApplication::Instance();
+ }
+
+ function ExtractByMask($array, $mask, $key_id=1, $ret_mode=1)
+ {
+// echo "extracting from <br>";
+// print_pre($array);
+ $rets = Array();
+ foreach ($array as $name => $val)
+ {
+ $regs = Array();
+// echo "checking $name<br>";
+ if (eregi($mask, $name, $regs)) {
+// echo "matched<br>";
+// print_pre($regs);
+ if ($ret_mode == 1) {
+ $rets[$regs[$key_id]] = $val;
+ }
+ else {
+ array_push($regs, $val);
+ $a_key = $regs[$key_id];
+ $i = 0;
+ while (array_key_exists($a_key, $rets)) {
+ $a_key.=$i;
+ $i++;
+ }
+ $rets[$a_key] = $regs;
+ }
+ }
+ }
+// echo "returning ";
+// print_pre($rets);
+ return $rets;
+ }
+
+}
+
+?>
\ No newline at end of file
Property changes on: trunk/core/kernel/utility/utilities.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/core/kernel/utility/event.php
===================================================================
--- trunk/core/kernel/utility/event.php (nonexistent)
+++ trunk/core/kernel/utility/event.php (revision 932)
@@ -0,0 +1,136 @@
+<?php
+ define('erFATAL',-1);
+ define('erFAIL',-2);
+ define('erSUCCESS',0);
+
+ class kEvent {
+
+ /**
+ * Event reference, that
+ * created this event
+ *
+ * @var kEvent
+ * @access public
+ */
+ var $MasterEvent;
+
+ /**
+ * Event name
+ *
+ * @var string
+ * @access public
+ */
+ var $Name;
+
+ /**
+ * Pseudo class name
+ *
+ * @var string
+ * @access public
+ */
+ var $Prefix;
+
+ /**
+ * Special, that is recognized
+ * by class with pseudo class
+ * equals to $Prefix attrbute.
+ *
+ * @var string
+ * @access public
+ */
+ var $Special;
+
+ /**
+ * Joined prefix and special,
+ * usually taken directly from
+ * tag beeing processes, to use
+ * in recallObject method
+ *
+ * @var string
+ */
+ var $Prefix_Special;
+
+ /**
+ * Stop event queue processing
+ * after this event
+ *
+ * @var bool
+ * @access public
+ */
+ var $cancelBubble=false;
+
+ /**
+ * Redirect is allowed after
+ * this event
+ *
+ * @var bool
+ * @access public
+ */
+ var $redirect=false;
+
+ /**
+ * Event processing result
+ *
+ * @var int
+ * @access public
+ */
+ var $status=erSUCCESS;
+
+ /**
+ * Each event specific only params,
+ * that they use for communication
+ *
+ * @var Array
+ * @access public
+ */
+ var $specificParams=Array();
+
+ /**
+ * Pseudo class used to create object,
+ * in case if one is not already created
+ *
+ * @var string
+ * @access public
+ */
+ var $pseudoClass='';
+
+ function setEventParam($name,$value)
+ {
+ $this->specificParams[$name]=$value;
+ }
+
+ function getEventParam($name)
+ {
+ return isset($this->specificParams[$name])?$this->specificParams[$name]:false;
+ }
+
+ function getPrefixSpecial($from_submit=false)
+ {
+ $separator=!$from_submit?'.':'_';
+ $ret=$this->Prefix.$separator.$this->Special;
+ return rtrim($ret,$separator);
+ }
+
+ /**
+ * Set's pseudo class that differs from
+ * the one specified in $Prefix
+ *
+ * @param string $appendix
+ * @access public
+ */
+ function setPseudoClass($appendix)
+ {
+ $this->pseudoClass=$this->Prefix.$appendix;
+ }
+
+ function Init($prefix,$special)
+ {
+ $this->Prefix=$prefix;
+ $this->pseudoClass=$prefix; // default value
+ $this->Special=$special;
+ $this->Prefix_Special = rtrim($this->Prefix.'.'.$this->Special,'.');
+ }
+
+ }
+
+?>
\ No newline at end of file
Property changes on: trunk/core/kernel/utility/event.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/core/kernel/utility/params.php
===================================================================
--- trunk/core/kernel/utility/params.php (nonexistent)
+++ trunk/core/kernel/utility/params.php (revision 932)
@@ -0,0 +1,170 @@
+<?php
+
+define ('FALSE_ON_NULL', 1);
+define ('EMPTY_ON_NULL', 2);
+
+class Params extends kBase {
+ var $_Params = Array();
+
+ function Params($params_str=null)
+ {
+ if ($params_str != '') $this->SplitParamsStr($params_str);
+ }
+
+ /**
+ * Splits tag params into associative array
+ *
+ * @param string $params_str
+ * @access private
+ */
+ function SplitParamsStr($params_str)
+ {
+ preg_match_all("/([a-zA-Z0-9_.]+)=([\"']{1,1})(.*?)(?<!\\\)\\2/", $params_str, $rets, PREG_SET_ORDER);
+
+ $values = Array();
+ foreach ($rets AS $key => $val){
+ $values[$val[1]] = str_replace('\\' . $val[2], $val[2], $val[3]);
+ }
+ $this->AddParams($values);
+ }
+
+ /**
+ * Sets new parameter value
+ *
+ * @param string $name
+ * @param string $val
+ * @access public
+ */
+ function Set($name, $val)
+ {
+ //echo "sessing params: [$name] = [$val] (class: <b>".get_class($this)."</b>)<br>";
+ $this->_Params[strtolower($name)] = $val;
+ }
+
+ /**
+ * Removes parameter
+ *
+ * @param string $name
+ * @access public
+ */
+ function Remove($name)
+ {
+ unset($this->_Params[$name]);
+ }
+
+ /**
+ * Gets parameter value by parameter name
+ *
+ * @param string $name
+ * @param int $mode
+ * @return string
+ * @access public
+ */
+ function Get($name, $mode=FALSE_ON_NULL)
+ {
+ // echo " name : '$name' || mode : $mode <br> ";
+ $name = strtolower($name);
+ if (array_key_exists($name, $this->_Params))
+ return $this->_Params[$name];
+ else
+ return $mode == FALSE_ON_NULL ? false : '';
+ }
+
+ /**
+ * Mass parameter setting from hash
+ *
+ * @param Array $params
+ * @access public
+ */
+ function AddParams($params)
+ {
+ if (!is_array($params)) return;
+ /*if (count($this->_Params) == 0) {
+ $this->_Params = $params;
+ }
+ else {*/
+ foreach ($params as $name => $val)
+ $this->Set(strtolower($name), $val);
+ //}
+ }
+
+ /**
+ * Return all paramters as hash
+ *
+ * @return Array
+ * @access public
+ */
+ function GetParams()
+ {
+ return $this->_Params;
+ }
+}
+
+/*class RefParams extends Params {
+
+ function Set($name, &$val)
+ {
+ $this->_Params[$name] =& $val;
+ }
+
+ function &Get($name)
+ {
+ if (isset($this->_Params[$name]))
+ return $this->_Params[$name];
+ else
+ return false;
+ }
+}*/
+
+// ################### TESTS ############################
+
+global $suite;
+if (isset($suite)) {
+ class TestParams extends TestCase {
+
+ function testParamsOperations()
+ {
+ $params =& new Params();
+ $params->Set('test_var', 24);
+ $this->AssertEquals(24, $params->Get('test_var'));
+ $this->AssertFalse($params->Get('none_existant_param'));
+ $res = $params->GetParams();
+ $this->AssertEquals(24, $res['test_var']);
+ }
+
+ function testSplitParams()
+ {
+ $params =& new Params('test_param="abc" another_param="7"');
+ $this->AssertEquals('abc', $params->Get('test_param'));
+ $this->AssertEquals('7', $params->Get('another_param'));
+ }
+ }
+ $suite->addTest(new TestSuite("TestParams"));
+}
+
+/*
+function getmicrotime(){
+ list($usec, $sec) = explode(" ",microtime());
+ //echo "Usec: $usec, sec: $sec<br>";
+ return ((float)$usec + (float)$sec);
+}
+
+$total = 0;
+$params =& new MyParams();
+$param_str = "param1=\"1\" param2='atessafa \'sdf'
+ params3=\"asd ' \\\"f\"";
+
+$param_str = "m:test escape1='-\"-' \t\t \n \t\n escape2=\"+\\\"+\" \n escape3='*\'*' escape4='=\='";
+
+//3852
+for ($i=0; $i<1; $i++)
+{
+ $start = getmicrotime();
+ $params->SplitParamsStr($param_str);
+ $end = getmicrotime();
+ $total += $end-$start;
+}
+
+printf ("total: %.8f; average: %.8f <br>", $total, $total/100);
+*/
+?>
\ No newline at end of file
Property changes on: trunk/core/kernel/utility/params.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/core/kernel/utility/debugger.php
===================================================================
--- trunk/core/kernel/utility/debugger.php (nonexistent)
+++ trunk/core/kernel/utility/debugger.php (revision 932)
@@ -0,0 +1,690 @@
+<?php
+
+ if(!defined('DBG_OPTIONS')) define('DBG_OPTIONS',0);
+
+ if(!defined('DBG_USE_HIGHLIGHT')) define('DBG_USE_HIGHLIGHT',1);
+
+ if(!defined('DBG_USE_SHUTDOWN_FUNC')) define('DBG_USE_SHUTDOWN_FUNC',1);
+ if(!defined('DBG_HANDLE_ERRORS')) define('DBG_HANDLE_ERRORS', isset($_REQUEST['debug_host']) ? 0 : 1);
+ if(!defined('DBG_RAISE_ON_WARNINGS')) define('DBG_RAISE_ON_WARNINGS',0);
+
+ if(!defined('DOC_ROOT')) define('DOC_ROOT',$_SERVER['DOCUMENT_ROOT']);
+ if(!defined('WINDOWS_ROOT')) define('WINDOWS_ROOT','w:');
+
+ if(!defined('WINDOWS_EDITOR'))
+ {
+ $dbg_editor = 0;
+ $dbg_editors[0] = Array('editor' => 'c:\Program Files\UltraEdit\uedit32.exe', 'params' => '%F/%L');
+ $dbg_editors[1] = Array('editor' => 'c:\Program Files\Zend\ZendStudio-4.0Beta\bin\ZDE.exe', 'params' => '%F');
+ define('WINDOWS_EDITOR',$dbg_editors[$dbg_editor]['editor'].' '.$dbg_editors[$dbg_editor]['params']);
+ unset($dbg_editors,$dbg_editor);
+ }
+
+ class Debugger
+ {
+ /**
+ * Debugger data for building report
+ *
+ * @var Array
+ */
+ var $Data = Array();
+ var $ProfilerData = Array();
+ var $RecursionStack = Array(); // prevent recursion when processing debug_backtrace() function results
+
+ var $TraceNextError=false;
+
+ var $Options = 0;
+ var $OptionsMap = Array('shutdown_func' => 1, 'error_handler' => 2,
+ 'output_buffer' => 4, 'highlight_output' => 8);
+
+ function Debugger()
+ {
+ $this->appendRequest();
+ }
+
+ function initOptions()
+ {
+
+
+ }
+
+ function setOption($name,$value)
+ {
+ if( !isset($this->OptionsMap[$name]) ) die('undefined debugger option: ['.$name.']<br>');
+ if($value)
+ {
+ $this->Options|=$this->OptionsMap[$name];
+ }
+ else
+ {
+ $this->Options=$this->Options&~$this->OptionsMap[$name];
+ }
+ }
+
+ function getOption($name)
+ {
+ if( !isset($this->OptionsMap[$name]) ) die('undefined debugger option: ['.$name.']<br>');
+ return ($this->Options & $this->OptionsMap[$name]) == $this->OptionsMap[$name];
+ }
+
+ /**
+ * Set's flag, that next error that occurs will
+ * be prepended by backtrace results
+ *
+ */
+ function traceNext()
+ {
+ $this->TraceNextError=true;
+ }
+
+ function dumpVars()
+ {
+ $dumpVars = func_get_args();
+ foreach($dumpVars as $varValue)
+ {
+ $this->Data[] = Array('value' => $varValue, 'debug_type' => 'var_dump');
+ }
+ }
+
+ function prepareHTML($dataIndex)
+ {
+ $Data =& $this->Data[$dataIndex];
+ if($Data['debug_type'] == 'html') return $Data['html'];
+
+ switch($Data['debug_type'])
+ {
+ case 'error':
+ $fileLink = $this->getFileLink($Data['file'],$Data['line']);
+ $ret = '<b class="debug_error">'.$this->getErrorNameByCode($Data['no']).'</b>: '.$Data['str'];
+ $ret .= ' in <b>'.$fileLink.'</b> on line <b>'.$Data['line'].'</b>';
+ return $ret;
+ break;
+
+ case 'var_dump':
+ $ret = $this->highlightString( print_r($Data['value'], true) );
+ return addslashes($ret);
+ break;
+
+ case 'trace':
+ ini_set('memory_limit','500M');
+ $trace =& $Data['trace'];
+
+ //return 'sorry';
+ //return $this->highlightString(print_r($trace,true));
+
+
+ $i = 0; $traceCount = count($trace);
+ $ret = '';
+ while($i < $traceCount)
+ {
+ $traceRec =& $trace[$i];
+ $argsID = 'trace_args_'.$dataIndex.'_'.$i;
+ if(isset($traceRec['file']))
+ {
+ $ret .= '<a href="javascript:toggleTraceArgs(\''.$argsID.'\');" title="Show/Hide Function Arguments"><b>Function</b></a>: '.$this->getFileLink($traceRec['file'],$traceRec['line'],$traceRec['class'].$traceRec['type'].$traceRec['function']);
+ $ret .= ' in <b>'.basename($traceRec['file']).'</b> on line <b>'.$traceRec['line'].'</b><br>';
+ }
+ else
+ {
+ $ret .= 'no file information available';
+ }
+ // ensure parameter value is not longer then 200 symbols
+ $this->processTraceArguments($traceRec['args']);
+ $args = $this->highlightString(print_r($traceRec['args'], true));
+ $ret .= '<div id="'.$argsID.'" style="display: none;">'.$args.'</div>';
+ $i++;
+ }
+ return $ret;
+ break;
+
+ case 'profiler':
+ $profileKey = $Data['profile_key'];
+ $Data =& $this->ProfilerData[$profileKey];
+ $runtime = ($Data['ends'] - $Data['begins']); // in seconds
+ return '<b>Name</b>: '.$Data['description'].'<br><b>Runtime</b>: '.$runtime.'s';
+ break;
+
+ default:
+ return 'incorrect debug data';
+ break;
+ }
+ }
+
+ function processTraceArguments(&$traceArgs)
+ {
+ foreach ($traceArgs as $argID => $argValue)
+ {
+ if( is_array($argValue) || is_object($argValue) )
+ {
+ if(is_object($argValue) && !in_array(get_class($argValue),$this->RecursionStack) )
+ {
+ // object & not in stack - ok
+ array_push($this->RecursionStack, get_class($argValue));
+ settype($argValue,'array');
+ $this->processTraceArguments($argValue);
+ array_pop($this->RecursionStack);
+ }
+ elseif(is_object($argValue) && in_array(get_class($argValue),$this->RecursionStack) )
+ {
+ // object & in stack - recursion
+ $traceArgs[$argID] = '**** RECURSION ***';
+ }
+ else
+ {
+ // normal array here
+ $this->processTraceArguments($argValue);
+ }
+ }
+ else
+ {
+ $traceArgs[$argID] = $this->cutStringForHTML($traceArgs[$argID]);
+ }
+ }
+ }
+
+ function cutStringForHTML($string)
+ {
+ if( strlen($string) > 200 ) $string = substr($string,0,50).' ...';
+ return $string;
+ }
+
+ /**
+ * Format SQL Query using predefined formatting
+ * and highlighting techniques
+ *
+ * @param string $sql
+ * @return string
+ */
+ function formatSQL($sql)
+ {
+ $sql = preg_replace('/(\n|\t| )+/is',' ',$sql);
+ $sql = preg_replace('/(CREATE TABLE|DROP TABLE|SELECT|UPDATE|REPLACE|INSERT|DELETE|VALUES|FROM|LEFT JOIN|WHERE|HAVING|GROUP BY|ORDER BY) /is', "\n\t$1 ",$sql);
+ return $this->highlightString($sql);
+ }
+
+ function highlightString($string)
+ {
+ if( defined('DBG_USE_HIGHLIGHT')&&DBG_USE_HIGHLIGHT )
+ {
+ $string = highlight_string('<?php '.$string.'?>', true);
+ return preg_replace('/&lt;\?(.*)php (.*)\?&gt;/s','$2',$string);
+ }
+ else
+ {
+ return $string;
+ }
+ }
+
+ function getFileLink($file, $lineno = 1, $title = '')
+ {
+ if(!$title) $title = $file;
+ return '<a href="javascript:editFile(\''.$this->getLocalFile($file).'\','.$lineno.');" title="'.$file.'">'.$title.'</a>';
+ }
+
+ function getLocalFile($remoteFile)
+ {
+ return str_replace(DOC_ROOT, WINDOWS_ROOT, $remoteFile);
+ }
+
+ function appendTrace()
+ {
+ $trace = debug_backtrace();
+ array_shift($trace);
+ $this->Data[] = Array('trace' => $trace, 'debug_type' => 'trace');
+ }
+
+ function appendHTML($html)
+ {
+ $this->Data[] = Array('html' => $html,'debug_type' => 'html');
+ }
+
+ /**
+ * Change debugger info that was already generated before.
+ * Returns true if html was set.
+ *
+ * @param int $index
+ * @param string $html
+ * @param string $type = {'append','prepend','replace'}
+ * @return bool
+ */
+ function setHTMLByIndex($index,$html,$type='append')
+ {
+ if( !isset($this->Data[$index]) || $this->Data[$index]['debug_type'] != 'html' )
+ {
+ return false;
+ }
+
+ switch ($type)
+ {
+ case 'append':
+ $this->Data[$index]['html'] .= '<br>'.$html;
+ break;
+ case 'prepend':
+ $this->Data[$index]['html'] = $this->Data[$index]['html'].'<br>'.$html;
+ break;
+ case 'replace':
+ $this->Data[$index]['html'] = $html;
+ break;
+ }
+ return true;
+ }
+
+ /**
+ * Move $debugLineCount lines of input from debug output
+ * end to beginning.
+ *
+ * @param int $debugLineCount
+ */
+ function moveToBegin($debugLineCount)
+ {
+ $lines = array_splice($this->Data,count($this->Data)-$debugLineCount,$debugLineCount);
+ $this->Data = array_merge($lines,$this->Data);
+ }
+
+ function appendRequest()
+ {
+ $script = $_SERVER['PATH_TRANSLATED'];
+ $this->appendHTML('ScriptName: <b>'.$this->getFileLink($script,1,basename($script)).'</b> (<b>'.dirname($script).'</b>)');
+ ob_start();
+ ?>
+ <table width="100%" border="0" cellspacing="0" cellpadding="4" class="flat_table">
+ <thead style="font-weight: bold;">
+ <td width="20">Src</td><td>Name</td><td>Value</td>
+ </thead>
+ <?php
+ foreach($_REQUEST as $key => $value)
+ {
+ if( !is_array($value) && trim($value) == '' )
+ {
+ $value = '<b class="debug_error">no value</b>';
+ }
+ else
+ {
+ $value = htmlspecialchars(print_r($value, true));
+ }
+ $src = isset($_GET[$key]) ? 'GE' : (isset($_POST[$key]) ? 'PO' : (isset($_COOKIE[$key]) ? 'CO' : '?') );
+ echo '<tr><td>'.$src.'</td><td>'.$key.'</td><td>'.$value.'</td></tr>';
+ }
+ ?>
+ </table>
+ <?php
+ $this->appendHTML( ob_get_contents() );
+ ob_end_clean();
+ }
+
+ function appendSession()
+ {
+ if( isset($_SESSION)&&$_SESSION )
+ {
+ $this->appendHTML('PHP Session: [<b>'.ini_get('session.name').'</b>]');
+ $this->dumpVars($_SESSION);
+ $this->moveToBegin(2);
+ }
+ }
+
+ function profileStart($key, $description)
+ {
+ $timeStamp = $this->getMoment();
+ $this->ProfilerData[$key] = Array('begins' => $timeStamp, 'ends' => 5000, 'debuggerRowID' => count($this->Data), 'description' => $description);
+ $this->Data[] = array('profile_key' => $key, 'debug_type' => 'profiler');
+ }
+
+ function profileFinish($key)
+ {
+ $this->ProfilerData[$key]['ends'] = $this->getMoment();
+ }
+
+ function getMoment()
+ {
+ list($usec, $sec) = explode(' ', microtime());
+ return ((float)$usec + (float)$sec);
+ }
+
+ function generateID()
+ {
+ list($usec, $sec) = explode(" ",microtime());
+
+ $id_part_1 = substr($usec, 4, 4);
+ $id_part_2 = mt_rand(1,9);
+ $id_part_3 = substr($sec, 6, 4);
+ $digit_one = substr($id_part_1, 0, 1);
+ if ($digit_one == 0) {
+ $digit_one = mt_rand(1,9);
+ $id_part_1 = ereg_replace("^0","",$id_part_1);
+ $id_part_1=$digit_one.$id_part_1;
+ }
+ return $id_part_1.$id_part_2.$id_part_3;
+ }
+
+
+ function getErrorNameByCode($errorCode)
+ {
+ switch($errorCode)
+ {
+ case E_USER_ERROR:
+ return 'Fatal Error';
+ break;
+
+ case E_WARNING:
+ case E_USER_WARNING:
+ return 'Warning';
+ break;
+
+ case E_NOTICE:
+ case E_USER_NOTICE:
+ return 'Notice';
+ break;
+
+ default:
+ return '';
+ break;
+ }
+ }
+
+ /**
+ * Generates report
+ *
+ */
+ function printReport($returnResult = false)
+ {
+ // show php session if any
+ $this->appendSession();
+
+ // ensure, that 1st line of debug output always is this one:
+ $this->appendHTML('<a href="javascript:toggleDebugLayer(27);">Hide Debugger</a>');
+ $this->moveToBegin(1);
+
+ $i = 0; $lineCount = count($this->Data);
+ ob_start();
+ ?>
+ <style type="text/css">
+ .flat_table TD {
+ border: 1px solid buttonface;
+ border-width: 1 1 0 0;
+
+ }
+
+ .debug_layer_table {
+ border-collapse: collapse;
+ width: 480px;
+ }
+
+ .debug_text, .debug_row_even TD, .debug_row_odd TD {
+ color: #000000;
+ font-family: Verdana;
+ font-size: 11px;
+ word-wrap: break-word;
+ }
+
+ .debug_cell {
+ border: 1px solid #FF0000;
+ padding: 2px;
+ word-wrap: break-word;
+ }
+
+ .debug_row_even {
+ background-color: #CCCCFF;
+ }
+
+ .debug_row_odd {
+ background-color: #FFFFCC;
+ }
+
+ .debug_layer_container {
+ left: 2px;
+ top: 1px;
+ width: 500px;
+ z-index: +1000;
+ position: absolute;
+ overflow: auto;
+ border: 2px solid;
+ padding: 3px;
+ border-top-color: threedlightshadow;
+ border-left-color: threedlightshadow;
+ border-right-color: threeddarkshadow;
+ border-bottom-color: threeddarkshadow;
+ background-color: buttonface;
+ }
+
+ .debug_layer {
+ padding: 0px;
+ width: 480px;
+ }
+
+ .debug_error {
+ color: #FF0000;
+ }
+ </style>
+ <div id="debug_layer" class="debug_layer_container" style="display: none;">
+ <div class="debug_layer">
+ <table width="100%" cellpadding="0" cellspacing="1" border="0" class="debug_layer_table">
+ <?php
+ while ($i < $lineCount)
+ {
+ echo '<tr class="debug_row_'.(($i % 2) ? 'odd' : 'even').'"><td class="debug_cell">'.$this->prepareHTML($i).'</td></tr>';
+ $i++;
+ }
+ ?>
+ </table>
+ </div>
+ </div>
+ <script language="javascript">
+ function getEventKeyCode($e)
+ {
+ var $KeyCode = 0;
+ if($e.keyCode) $KeyCode = $e.keyCode;
+ else if($e.which) $KeyCode = $e.which;
+ return $KeyCode;
+ }
+
+ function keyProcessor($e)
+ {
+ if(!$e) $e = window.event;
+ var $KeyCode = getEventKeyCode($e);
+ if($KeyCode==123||$KeyCode==27) // F12 or ESC
+ {
+ toggleDebugLayer($KeyCode);
+ $e.cancelBubble = true;
+ if($e.stopPropagation) $e.stopPropagation();
+ }
+ }
+
+ function toggleDebugLayer($KeyCode)
+ {
+ var $isVisible=false;
+ var $DebugLayer = document.getElementById('debug_layer');
+ if( typeof($DebugLayer) != 'undefined' )
+ {
+ $isVisible = ($DebugLayer.style.display == 'none')?false:true;
+ if(!$isVisible&&$KeyCode==27) return false;
+
+ resizeDebugLayer(null);
+ $DebugLayer.style.display = $isVisible?'none':'block';
+ }
+ }
+
+ function prepareSizes($Prefix)
+ {
+ var $ret = '';
+ $ret = eval('document.body.'+$Prefix+'Top')+'; ';
+ $ret += eval('document.body.'+$Prefix+'Left')+'; ';
+ $ret += eval('document.body.'+$Prefix+'Height')+'; ';
+ $ret += eval('document.body.'+$Prefix+'Width')+'; ';
+ return $ret;
+ }
+
+ function resizeDebugLayer($e)
+ {
+ if(!$e) $e = window.event;
+ var $DebugLayer = document.getElementById('debug_layer');
+ var $TopMargin = 1;
+ if( typeof($DebugLayer) != 'undefined' )
+ {
+ $DebugLayer.style.top = parseInt(document.body.offsetTop + document.body.scrollTop) + $TopMargin;
+ $DebugLayer.style.height = document.body.clientHeight - $TopMargin - 5;
+ }
+ window.parent.status = 'OFFSET: '+prepareSizes('offset')+' | SCROLL: '+prepareSizes('scroll')+' | CLIENT: '+prepareSizes('client');
+ window.parent.status += 'DL Info: '+$DebugLayer.style.top+'; S.AH: '+screen.availHeight;
+ return true;
+ }
+
+ function SetClipboard($data)
+ {
+ if (window.clipboardData)
+ {
+ window.clipboardData.setData('Text', $data);
+ }
+ else if (window.netscape)
+ {
+ //netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
+ var clip = Components.classes['@mozilla.org/widget/clipboard;1'].createInstance(Components.interfaces.nsIClipboard);
+ if (!clip) return;
+
+ var trans = Components.classes['@mozilla.org/widget/transferable;1'].createInstance(Components.interfaces.nsITransferable);
+ if (!trans) return;
+
+ trans.addDataFlavor('text/unicode');
+ var str = new Object();
+ var len = new Object();
+ var str = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString);
+
+ var $copytext=$data;
+
+ str.data=$copytext;
+
+ trans.setTransferData("text/unicode",str,$copytext.length*2);
+ var clipid=Components.interfaces.nsIClipboard;
+ if (!clip) return false;
+
+ clip.setData(trans,null,clipid.kGlobalClipboard);
+ }
+
+ }
+
+ function showProps($Obj, $Name)
+ {
+ var $ret = '';
+ for($Prop in $Obj)
+ {
+ $ret += $Name+'.'+$Prop+' = '+$Obj[$Prop]+"\n";
+ }
+ return $ret;
+ }
+
+ function editFile($fileName,$lineNo)
+ {
+ if(!document.all)
+ {
+ alert('Only works in IE');
+ return;
+ }
+
+ var $editorPath = '<?php echo defined('WINDOWS_EDITOR') ? addslashes(WINDOWS_EDITOR) : '' ?>';
+ if($editorPath)
+ {
+ var $obj = new ActiveXObject("LaunchinIE.Launch");
+ $editorPath = $editorPath.replace('%F',$fileName);
+ $editorPath = $editorPath.replace('%L',$lineNo);
+ $obj.LaunchApplication($editorPath);
+ }
+ else
+ {
+ alert('Editor path not defined!');
+ }
+ }
+
+ function toggleTraceArgs($ArgsLayerID)
+ {
+ var $ArgsLayer = document.getElementById($ArgsLayerID);
+ $ArgsLayer.style.display = ($ArgsLayer.style.display == 'none') ? 'block' : 'none';
+ }
+
+
+ document.onkeydown = keyProcessor;
+ window.onresize = resizeDebugLayer;
+ window.onscroll = resizeDebugLayer;
+ window.focus();
+ if( typeof($isFatalError) != 'undefined' && $isFatalError == 1 || <?php echo DBG_RAISE_ON_WARNINGS; ?> )
+ {
+ toggleDebugLayer();
+ }
+ if( typeof($isFatalError) != 'undefined' && $isFatalError == 1)
+ {
+ document.getElementById('debug_layer').scrollTop = 10000000;
+ }
+ </script>
+ <?php
+
+ if($returnResult)
+ {
+ $ret = ob_get_contents();
+ ob_clean();
+ return $ret;
+ }
+ else
+ {
+ ob_end_flush();
+ }
+ }
+
+ /**
+ * User-defined error handler
+ *
+ * @param int $errno
+ * @param string $errstr
+ * @param string $errfile
+ * @param int $errline
+ * @param array $errcontext
+ */
+ function saveError($errno, $errstr, $errfile = '', $errline = '', $errcontext = '')
+ {
+ //echo '<b>error</b> ['.$errno.'] = ['.$errstr.']<br>';
+ $errorType = $this->getErrorNameByCode($errno);
+ if(!$errorType)
+ {
+ trigger_error('Unknown error type ['.$errno.']', E_USER_ERROR);
+ return false;
+ }
+ if( strpos($errfile,'eval()\'d code') !== false )
+ {
+ $errstr = '[<b>EVAL</b>, line <b>'.$errline.'</b>]: '.$errstr;
+ $tmpStr = $errfile;
+ $pos = strpos($tmpStr,'(');
+ $errfile = substr($tmpStr,0,$pos);
+ $pos++;
+ $errline = substr($tmpStr,$pos,strpos($tmpStr,')',$pos)-$pos);
+ }
+ if($this->TraceNextError)
+ {
+ $this->appendTrace();
+ $this->TraceNextError=false;
+ }
+ $this->Data[] = Array('no' => $errno, 'str' => $errstr, 'file' => $errfile, 'line' => $errline, 'context' => $errcontext, 'debug_type' => 'error');
+
+ if( substr($errorType,0,5) == 'Fatal')
+ {
+ echo '<script language="javascript">var $isFatalError = 1;</script>';
+ exit;
+ }
+ }
+
+ function saveToFile($msg)
+ {
+ $fp = fopen($_SERVER['DOCUMENT_ROOT'].'/vb_debug.txt', 'a');
+ fwrite($fp,$msg."\n");
+ fclose($fp);
+ }
+
+ }
+
+ function ConstOn($const_name)
+ {
+ return defined($const_name)&&constant($const_name);
+ }
+
+ $debugger = new Debugger();
+ if(ConstOn('DBG_HANDLE_ERRORS')) set_error_handler( array(&$debugger,'saveError') );
+ if(ConstOn('DBG_USE_SHUTDOWN_FUNC')) register_shutdown_function( array(&$debugger,'printReport') );
+
+
+?>
\ No newline at end of file
Property changes on: trunk/core/kernel/utility/debugger.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/core/kernel/utility/http_query.php
===================================================================
--- trunk/core/kernel/utility/http_query.php (nonexistent)
+++ trunk/core/kernel/utility/http_query.php (revision 932)
@@ -0,0 +1,225 @@
+<?php
+
+class HTTPQuery extends Params {
+ /**
+ * $_POST vars
+ *
+ * @var Array
+ * @access private
+ */
+ var $Post;
+
+ /**
+ * $_GET vars
+ *
+ * @var Array
+ * @access private
+ */
+ var $Get;
+ /**
+ * $_COOKIE vars
+ *
+ * @var Array
+ * @access private
+ */
+ var $Cookie;
+
+ /**
+ * $_SERVER vars
+ *
+ * @var Array
+ * @access private
+ */
+ var $Server;
+
+ /**
+ * $_ENV vars
+ *
+ * @var Array
+ * @access private
+ */
+ var $Env;
+
+ /**
+ * Order in what write
+ * all vars together in
+ * the same array
+ *
+ * @var string
+ */
+ var $Order;
+
+ /**
+ * Uploaded files info
+ *
+ * @var Array
+ * @access private
+ */
+ var $Files;
+
+ /**
+ * Loads info from $_POST, $_GET and
+ * related arrays into common place
+ *
+ * @param string $order
+ * @return HTTPQuery
+ * @access public
+ */
+ function HTTPQuery($order='CGPF')
+ {
+ $this->Order = $order;
+ $this->AddAllVars();
+ ini_set("magic_quotes_gpc", 0);
+ }
+
+ /**
+ * All all requested vars to
+ * common storage place
+ *
+ * @access private
+ */
+ function AddAllVars()
+ {
+ for ($i=0; $i < strlen($this->Order); $i++)
+ {
+ $current = $this->Order[$i];
+ switch ($current) {
+ case 'G':
+ $this->Get =$this->AddVars($_GET);
+ break;
+ case 'P':
+ $my_post = $this->post_convert($_POST); // needed ?
+ $this->Post = $this->AddVars($_POST);
+ break;
+ case 'C':
+ $this->Cookie = $this->AddVars($_COOKIE);
+ break;
+ case 'E';
+ $this->Env = $this->AddVars($_ENV);
+ break;
+ case 'S';
+ $this->Server = $this->AddVars($_SERVER);
+ break;
+ case 'F';
+ $this->Files = $this->AddVars($_FILES);
+ break;
+ }
+ }
+ }
+
+ function post_convert($array)
+ {
+ $out = Array();
+ foreach ($array as $key => $val) {
+ if ( ereg("\|\|",$key)) {
+ $key = str_replace("||",".",$key);
+ }
+ else
+ $out[$key] = $val;
+ }
+ }
+
+ /**
+ * Saves variables from array specified
+ * into common variable storage place
+ *
+ * @param Array $array
+ * @return Array
+ * @access private
+ */
+ function AddVars($array)
+ {
+ foreach ($array as $key => $val) {
+ if (get_magic_quotes_gpc())
+ {
+
+ if ( is_array($val) )
+ {
+ foreach ($val as $key_array => $val_array)
+ {
+ if( is_array($val_array) )
+ {
+ $array[$key][$key_array] = $this->AddVars($val_array);
+ }
+ else
+ {
+ $array[$key][$key_array] = stripslashes($val_array);
+ }
+
+ }
+ $this->Set($key, $array[$key]);
+ }
+ else {
+ $array[$key] = stripslashes($val);
+ $this->Set($key, $array[$key]);
+ }
+
+
+ }
+ else {
+ $this->Set($key, $val);
+ }
+ }
+ return $array;
+ }
+
+ /**
+ * Returns the hash of http params
+ * matching the mask with values
+ *
+ * @param string $mask
+ * @return Array
+ * @access public
+ */
+ function GetSelectedValues($mask)
+ {
+ return $this->Application->ExtractByMask($this->Vars, $mask);
+ }
+
+ /**
+ * Returns the sprintf'ed by format list of
+ * http params matching the mask and set to on
+ *
+ * @param string $mask
+ * @param string $format
+ * @return string
+ * @access public
+ */
+ function GetSelectedIDs($mask, $format)
+ {
+ if ($mask == '') return;
+ $result = '';
+ foreach ($this->GetParams() as $name => $val)
+ {
+ if (eregi($mask, $name, $regs) && $val == 'on') {
+
+ $result.= sprintf($format, $regs[1]);
+ }
+ }
+ return $result;
+ }
+
+ /**
+ * Returns the sprintf'ed by format list of
+ * http params matching the mask and set to on
+ *
+ * @param string $mask
+ * @param string $value_mask
+ * @return Array
+ * @access public
+ */
+ function GetSelectedIDsArray($mask, $value_mask="%s,")
+ {
+ $str = $this->GetSelectedIDs($mask, $value_mask);
+ $str = rtrim($str, ',');
+ if (!empty($str)) {
+ $ids = split(',', $str);
+ if ($ids !== false)
+ return $ids;
+ else return Array();
+ }
+ else return Array();
+ }
+}
+
+?>
\ No newline at end of file
Property changes on: trunk/core/kernel/utility/http_query.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/core/kernel/utility/unit_config_reader.php
===================================================================
--- trunk/core/kernel/utility/unit_config_reader.php (nonexistent)
+++ trunk/core/kernel/utility/unit_config_reader.php (revision 932)
@@ -0,0 +1,163 @@
+<?php
+
+ class kUnitConfigReader extends kBase {
+
+ /**
+ * Configs readed
+ *
+ * @var Array
+ * @access private
+ */
+ var $configData=Array();
+
+ /**
+ * Module names found during
+ * config reading
+ *
+ * @var Array
+ */
+ var $modules=Array();
+
+ /**
+ * Scan kernel and user classes
+ * for available configs
+ *
+ * @access protected
+ */
+ function Init($prefix,$special)
+ {
+ parent::Init($prefix,$special);
+ $this->scanModules(MODULES_PATH);
+ }
+
+ /**
+ * Read configs from all directories
+ * on path specified
+ *
+ * @param string $folderPath
+ * @access public
+ */
+ function processFolder($folderPath)
+ {
+ $fh=opendir($folderPath);
+ while(($sub_folder=readdir($fh)))
+ {
+ $full_path=$folderPath.'/'.$sub_folder;
+ if( $this->isDir($full_path) && file_exists($this->getConfigName($full_path)) )
+ {
+ include_once $this->getConfigName($full_path);
+ $prefix=$config['Prefix'];
+ $config['BasePath']=$full_path;
+ $this->configData[$prefix] = $config;
+ $this->parseConfig($prefix);
+ }
+ }
+ }
+
+
+ function scanModules($folderPath)
+ {
+ $fh=opendir($folderPath);
+ while(($sub_folder=readdir($fh)))
+ {
+ $full_path=$folderPath.'/'.$sub_folder;
+ if( $this->isDir($full_path) )
+ {
+ $this->processFolder($full_path);
+ }
+ }
+ }
+
+ /**
+ * Register nessasary classes
+ *
+ * @param string $prefix
+ * @access private
+ */
+ function parseConfig($prefix)
+ {
+ $config =& $this->configData[$prefix];
+ $event_manager =& $this->Application->recallObject('EventManager');
+ $class_params=Array('ItemClass','ListClass','EventHandlerClass','TagProcessorClass');
+ foreach($class_params as $param_name)
+ {
+ $class_info =& $config[$param_name];
+ $pseudo_class = $this->getPrefixByParamName($param_name,$prefix);
+ $this->Application->registerClass( $class_info['class'],
+ $config['BasePath'].'/'.$class_info['file'],
+ $pseudo_class);
+ $event_manager->registerBuildEvent($pseudo_class,$class_info['build_event']);
+ }
+ }
+
+ /**
+ * Reads unit (specified by $prefix)
+ * option specified by $option
+ *
+ * @param string $prefix
+ * @param string $option
+ * @return string
+ * @access public
+ */
+ function getUnitOption($prefix,$name)
+ {
+ return $this->configData[$prefix][$name];
+ }
+
+ /**
+ * Set's new unit option value
+ *
+ * @param string $prefix
+ * @param string $name
+ * @param string $value
+ * @access public
+ */
+ function setUnitOption($prefix,$name,$value)
+ {
+ $this->configData[$prefix][$name]=$value;
+ }
+
+ function getPrefixByParamName($paramName,$prefix)
+ {
+ $pseudo_class_map=Array(
+ 'ItemClass'=>'%s',
+ 'ListClass'=>'%s_List',
+ 'EventHandlerClass'=>'%s_EventHandler',
+ 'TagProcessorClass'=>'%s_TagProcessor'
+ );
+ return sprintf($pseudo_class_map[$paramName],$prefix);
+ }
+
+ /**
+ * Get's config file name based
+ * on folder name supplied
+ *
+ * @param string $folderPath
+ * @return string
+ * @access private
+ */
+ function getConfigName($folderPath)
+ {
+ return $folderPath.'/'.basename($folderPath).'_config.php';
+ }
+
+ /**
+ * is_dir ajustment to work with
+ * directory listings too
+ *
+ * @param string $folderPath
+ * @return bool
+ * @access private
+ */
+ function isDir($folderPath)
+ {
+ $base_name=basename($folderPath);
+ $ret=!($base_name=='.'||$base_name=='..');
+ return $ret&&is_dir($folderPath);
+ }
+
+
+ }
+
+
+?>
\ No newline at end of file
Property changes on: trunk/core/kernel/utility/unit_config_reader.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/core/kernel/utility/configuration.php
===================================================================
--- trunk/core/kernel/utility/configuration.php (nonexistent)
+++ trunk/core/kernel/utility/configuration.php (revision 932)
@@ -0,0 +1,87 @@
+<?php
+
+
+// need to be rewrited
+
+class ConfigItem extends kDBItem
+{
+ var $Application;
+
+ function ConfigItem($Id)
+ {
+ $this->Application =& KernelApplication::Instance();
+ $this->id_field = 'name';
+ $this->table_name = 'config';
+ $this->CreateField('name','',1,1);
+ $this->CreateField('value','',1,1);
+ $this->CreateField('config_description','', 0, 0);
+ $this->DisplayErrors = 0;
+ $this->DisplayQueries = 0;
+ parent::DBItem($Id);
+ }
+
+ function Update()
+ {
+ $ret = parent::Update();
+ // echo " update ".$this->GetDBField('name')."<br>";
+ if ( $ret AND ereg("(per_page)",$this->GetDBField('name'))) {
+ $this->Application->StoreVar(
+ $this->GetDBField('name'),
+ $this->GetDBField('value')
+ );
+ }
+ return $ret;
+ }
+}
+
+class ConfigList extends kDBList
+{
+ function ConfigList($sql, $query_now=0, $owner=null)
+ {
+ parent::kDBList($sql, $query_now, $owner);
+ $this->Special = $owner->Params['special'];
+ switch ($this->Special)
+ {
+ default:
+ $this->sql = " SELECT * FROM config ";
+ };
+ $this->DisplayQueries = 0;
+ }
+
+ function &NewItem ()
+ {
+ $new_item = new ConfigItem(NULL);
+ return $new_item;
+ }
+
+ function GetOption($name)
+ {
+ if ($this->Find('name', $name))
+ return $this->GetCurrentFieldValue('value');
+ else
+ return false;
+ }
+
+ function SetOption($name, $value)
+ {
+ if ($this->Find('name', $name)) {;
+ $this->SetCurrentFieldValue('value', $value);
+ $tmp =& $this->GetCurrentRec();
+ $tmp->Update();
+ }
+ else {
+ $push_hash = Array('name'=>$name, 'value'=>$value);
+ $id = array_push($this->Records, $push_hash);
+ if (count($this->IndexFields) > 0) {
+ foreach ($this->IndexFields as $key) {
+ if (is_string($push_hash[$key])) $store_key = strtolower($push_hash[$key]);
+ else $store_key = $push_hash[$key];
+ $this->Indexes[$key][$store_key] = $id-1;
+ }
+ }
+ $this->last_rec++;
+ }
+ }
+}
+
+?>
\ No newline at end of file
Property changes on: trunk/core/kernel/utility/configuration.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/core/kernel/utility/factory.php
===================================================================
--- trunk/core/kernel/utility/factory.php (nonexistent)
+++ trunk/core/kernel/utility/factory.php (revision 932)
@@ -0,0 +1,158 @@
+<?php
+
+//include_once(KERNEL_PATH."/mvc/controllers/grid_controller.php");
+//include_once(KERNEL_PATH."/mvc/controllers/item_controller.php");
+
+ class kFactory extends kBase {
+
+ /**
+ * Where all created objects are stored
+ *
+ * @var Array
+ * @access private
+ */
+ var $Storage=Array();
+
+ /**
+ * Map between class name and file name
+ * where class definition can be found.
+ * File path absolute!
+ *
+ * @var Array
+ * @access private
+ */
+ var $Files=Array();
+
+ /**
+ * Map class names to their pseudo
+ * class names, e.g. key=pseudo_class,
+ * value=real_class_name
+ *
+ * @var Array
+ * @access private
+ */
+ var $realClasses=Array();
+
+
+ /**
+ * Splits any mixing of prefix and
+ * special into correct ones
+ *
+ * @param string $prefix_special
+ * @return Array
+ * @access public
+ */
+ function processPrefix($prefix_special)
+ {
+ // l.pick, l, m.test_TagProcessor
+
+ $tmp=explode('_',$prefix_special,2);
+ $tmp[0]=explode('.',$tmp[0]);
+
+ $prefix=$tmp[0][0];
+ if( isset($tmp[1]) )
+ {
+ $prefix.='_'.$tmp[1];
+ }
+ $special=isset($tmp[0][1])?$tmp[0][1]:'';
+
+ return Array('prefix'=>$prefix,'special'=>$special);
+ }
+
+
+ /**
+ * Returns object using params specified,
+ * creates it if is required
+ *
+ * @param string $name
+ * @param string $pseudo_class
+ * @param Array $event_params
+ * @return Object
+ */
+ function &getObject($name,$pseudo_class='',$event_params=Array())
+ {
+ // $name = 'l.pick', $pseudo_class = 'l'
+ //echo 'N: '.$name.' - P: '.$pseudo_class."\n";
+ $ret=$this->processPrefix($name);
+ if(!$pseudo_class)$pseudo_class=$ret['prefix'];
+ $name=rtrim($name,'.');
+ if( isset($this->Storage[$name]) ) return $this->Storage[$name];
+
+ if(!isset($this->realClasses[$pseudo_class]))
+ {
+ $this->Application->KernelDie('RealClass not defined for pseudo_class <b>'.$pseudo_class.'</b>');
+ }
+
+ $this->Storage[$name] =& $this->makeClass($pseudo_class);
+ $this->Storage[$name]->Init($ret['prefix'],$ret['special']);
+
+ $prefix=$this->Storage[$name]->Prefix;
+ $special=$this->Storage[$name]->Special;
+
+ $event_manager =& $this->getObject('EventManager');
+ $event =& $event_manager->getBuildEvent($pseudo_class);
+ if($event)
+ {
+ $event->Init($prefix,$special);
+ foreach($event_params as $param_name=>$param_value)
+ {
+ $event->setEventParam($param_name,$param_value);
+ }
+ $this->Application->HandleEvent($event);
+ }
+
+ return $this->Storage[$name];
+ }
+
+ /**
+ * Includes file containing class
+ * definition for real class name
+ *
+ * @param string $real_class
+ * @access private
+ */
+ function includeClassFile($real_class)
+ {
+ if(!$this->Files[$real_class]) $this->Application->KernelDie('<b>Fatal error: Real Class '.$real_class.' is not registered with the Factory</b><br>');
+ if(!file_exists($this->Files[$real_class])) $this->Application->KernelDie('<b>Fatal error: Include file for class '.$real_class.' ('.$this->Files[$real_class].') does not exists</b><br>');
+ include_once($this->Files[$real_class]);
+ }
+
+ /**
+ * Get's real class name for pseudo class,
+ * includes class file and creates class
+ * instance
+ *
+ * @param string $pseudo_class
+ * @return Object
+ * @access private
+ */
+ function &makeClass($pseudo_class)
+ {
+ $real_class=$this->realClasses[$pseudo_class];
+ $this->includeClassFile($real_class);
+ /*if (!class_exists($real_class))
+ {
+ $this->Application->KernelDie ("<b>Fatal error: Real Class $real_class (pseudo class $pseudo_class) not found in its registered file ".$this->Files[$pseudo_class].'<br>');
+ }*/
+ return new $real_class();
+ }
+
+ /**
+ * Registers new class in the factory
+ *
+ * @param string $real_class
+ * @param string $file
+ * @param string $pseudo_class
+ * @access public
+ */
+ function registerClass($real_class,$file,$pseudo_class=null)
+ {
+ if(!isset($pseudo_class)) $pseudo_class = $real_class;
+ if(!isset($this->Files[$real_class])) $this->Files[$real_class]=$file;
+ $this->realClasses[$pseudo_class]=$real_class;
+ }
+
+ }
+
+?>
\ No newline at end of file
Property changes on: trunk/core/kernel/utility/factory.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/core/kernel/event_handler.php
===================================================================
--- trunk/core/kernel/event_handler.php (nonexistent)
+++ trunk/core/kernel/event_handler.php (revision 932)
@@ -0,0 +1,108 @@
+<?php
+
+ /**
+ * Note:
+ * 1. When adressing variables from submit containing
+ * Prefix_Special as part of their name use
+ * $event->getPrefixSpecial(true) instead of
+ * $event->Prefix_Special as usual. This is due PHP
+ * is converting "." symbols in variable names during
+ * submit info "_". $event->getPrefixSpecial optional
+ * 1st parameter returns correct corrent Prefix_Special
+ * for variables beeing submitted such way (e.g. variable
+ * name that will be converted by PHP: "users.read_only_id"
+ * will be submitted as "users_read_only_id".
+ *
+ * 2. When using $this->Application-LinkVar on variables submitted
+ * from form which contain $Prefix_Special then note 1st item. Example:
+ * LinkVar($event->getPrefixSpecial(true).'_varname',$event->Prefix_Special.'_varname')
+ *
+ */
+
+
+ /**
+ * Default event handler. Mostly abstract class
+ *
+ */
+ class kEventHandler extends kBase {
+
+ /**
+ * Process Event
+ *
+ * @param kEvent $event
+ * @access public
+ */
+ function processEvent(&$event)
+ {
+ if( method_exists($this,$event->Name) )
+ {
+ $event_name = $event->Name;
+ $this->$event_name(&$event);
+ if($event->status==erSUCCESS && $event->redirect && strlen($event->redirect) > 0 )
+ {
+ $this->Application->Redirect($event->redirect);
+ }
+ }
+ else
+ {
+ $this->Application->KernelDie('event <b>'.$event->Name.'</b> not implemented in class <b>'.get_class($this).'</b>');
+ }
+ }
+
+ /**
+ * Sample dummy event
+ *
+ * @param kEvent $event
+ * @access protected
+ */
+ function OnBuild(&$event)
+ {
+ /*echo 'building: <br>';
+ print_pre($event);*/
+ }
+
+ /**
+ * Retunrs object used in event
+ *
+ * @param kEvent $event
+ * @access protected
+ */
+ function &createObject(&$event)
+ {
+ return $this->Application->recallObject($event->Prefix_Special,$event->pseudoClass);
+ }
+
+ /**
+ * Apply some special processing to
+ * object beeing recalled before using
+ * it in other events that call prepareObject
+ *
+ * @param Object $object
+ * @param kEvent $event
+ * @access protected
+ */
+ function prepareObject(&$object,&$event)
+ {
+ // processing here
+ }
+
+ /**
+ * Creates new event as child of
+ * event passed as $event param
+ *
+ * @param kEvent $event
+ * @access protected
+ */
+ function &inheritEvent(&$event)
+ {
+ $child_event = new kEvent();
+ $child_event->MasterEvent =& $event;
+ $child_event->Prefix=$event->Prefix;
+ $child_event->Special=$event->Special;
+ $child_event->Prefix_Special=$event->Prefix_Special;
+ return $child_event;
+ }
+ }
+
+
+?>
\ No newline at end of file
Property changes on: trunk/core/kernel/event_handler.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/core/kernel/db/db_tag_processor.php
===================================================================
--- trunk/core/kernel/db/db_tag_processor.php (nonexistent)
+++ trunk/core/kernel/db/db_tag_processor.php (revision 932)
@@ -0,0 +1,138 @@
+<?php
+
+class kDBTagProcessor extends TagProcessor {
+
+ /**
+ * Prints list content using block specified
+ *
+ * @param Array $params
+ * @return string
+ * @access public
+ */
+ function PrintList($params)
+ {
+ $list =& $this->Application->recallObject( $this->getPrefixSpecial(), $this->Prefix.'_List',$params);
+ $id_field = $this->Application->getUnitOption($this->Prefix,'IDField');
+ //<inp:cand_MapField field="candidate_id" var_name="cand_id"/>
+
+ /*$parser =& $this->Application->recallObject('TemplateParser');
+
+ // only useful in case in inside prinklist block we have another
+ // tagprocessor who wants to findout out printlist prefix and special
+ $parser->SetParam('prefix', $this->Prefix);
+ $parser->SetParam('special', $this->Special);*/
+
+ $list->Query();
+ $o = '';
+ $list->GoFirst();
+
+ $block_params=$this->prepareTagParams($params);
+ $block_params['name']=$params['block'];
+ $block_params['pass_params']='true';
+
+ while (!$list->EOL())
+ {
+ $this->Application->SetVar( $this->getPrefixSpecial().'_id', $list->GetDBField($id_field) );
+ $o.= $this->Application->ParseBlock($block_params, 1);
+ $list->GoNext();
+ }
+ return $o;
+ }
+
+ /**
+ * Append prefix and special to tag
+ * params (get them from tagname) like
+ * they were really passed as params
+ *
+ * @param Array $tag_params
+ * @return Array
+ * @access protected
+ */
+ function prepareTagParams($tag_params)
+ {
+ $ret=$tag_params;
+ $ret['Prefix']=$this->Prefix;
+ $ret['Special']=$this->Special;
+ $ret['PrefixSpecial']=$this->getPrefixSpecial();
+ return $ret;
+ }
+
+ /**
+ * Get's reuested field value
+ *
+ * @param Array $params
+ * @return string
+ * @access public
+ */
+ function Field($params)
+ {
+ $field = $params['field'];
+ $object =& $this->Application->recallObject($this->getPrefixSpecial(),$this->Prefix, $params);
+
+ $value = $object->GetField($field);
+
+ if (isset($params['nl2br'])) $value = nl2br($value);
+
+ return $value;
+ }
+
+ /**
+ * Print grid pagination using
+ * block names specified
+ *
+ * @param Array $params
+ * @return string
+ * @access public
+ */
+ function PrintPages($params)
+ {
+ $prefix_special=$this->getPrefixSpecial();
+ $object =& $this->Application->recallObject($prefix_special,$this->Prefix.'_List',$params);
+ $total = $object->GetTotalPages();
+
+ $o = '';
+ $this->Application->SetVar($prefix_special.'_event','OnSetPage');
+ $current_page = $this->Application->RecallVar($prefix_special.'_page');
+
+ $block_params=$this->prepareTagParams($params);
+
+ for ($i=1; $i<=$total; $i++)
+ {
+ $this->Application->SetVar($prefix_special.'_page',$i);
+ $block = $params[ (($i==$current_page)?'active':'inactive').'_block' ];
+ $block_params['name']=$block;
+ $block_params['page']=$i;
+ $o .= $this->Application->ParseBlock($block_params, 1);
+ }
+
+ return $o;
+ }
+
+ /*function MapField($params)
+ {
+ $object =& $this->Application->recallObject($this->Prefix.'.'.$this->Special);
+ $value = $object->GetField($params['field']);
+ $this->Application->SetVar($params['var_name'],$value);
+ }*/
+
+ /**
+ * Returns input field name to
+ * be placed on form (for correct
+ * event processing)
+ *
+ * @param Array $params
+ * @return string
+ * @access public
+ */
+ function InputName($params)
+ {
+ $prefix_special=$this->getPrefixSpecial();
+ $item = $this->Application->recallObject($prefix_special);
+ return $prefix_special.'['.$item->GetID().']['.$params['field'].']';
+ }
+
+
+
+}
+
+?>
\ No newline at end of file
Property changes on: trunk/core/kernel/db/db_tag_processor.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/core/kernel/db/dblist.php
===================================================================
--- trunk/core/kernel/db/dblist.php (nonexistent)
+++ trunk/core/kernel/db/dblist.php (revision 932)
@@ -0,0 +1,393 @@
+<?php
+
+/**
+* DBList
+*
+* Desciption
+* @package kernel4
+*/
+class kDBList extends kDBBase {
+
+ /**
+ * Description
+ *
+ * @var array
+ * @access public
+ */
+ var $OrderFields;
+
+ /**
+ * Holds counted total number of records in the query - without pagination
+ *
+ * @var int
+ * @access public
+ */
+ var $RecordsCount;
+
+
+ /**
+ * Record count selected to be
+ * showed on current page
+ *
+ * @var unknown_type
+ */
+ var $SelectedCount=0;
+
+ /**
+ * Array of records selected
+ *
+ * @var Array
+ * @access private
+ */
+ var $Records;
+
+ var $CurrentIndex = 0;
+
+ /**
+ * Description
+ *
+ * @var int
+ * @access public
+ */
+ var $PerPage;
+
+ /**
+ * Description
+ *
+ * @var int
+ * @access public
+ */
+ var $TotalPages;
+
+ /**
+ * Holds current page number - used when forming LIMIT clause of SELECT statement
+ *
+ * @var int
+ * @access public
+ */
+ var $Page;
+
+ /**
+ * Holds offset for LIMIT clause, calculated in {@link kDBList::PerPage()}
+ *
+ * @var int
+ * @access private
+ */
+ var $Offset;
+
+
+ /**
+ * Count SQL was already issued on query
+ *
+ * @var bool
+ * @access private
+ */
+ var $hasCounted = false;
+
+ /**
+ * Creates kDBList
+ *
+ * @return kDBList
+ */
+ function kDBList() {
+ parent::kDBBase();
+ $this->OrderFields = Array();
+ $this->PerPage = -1;
+ }
+
+ /**
+ * Sets counted part of SELECT query used in grouped queries
+ *
+ * When using queries containing GROUP BY clause, the SELECT part may contain aggregate functions such as SUM(), COUNT() etc.
+ * the part of the query with this functions should be set as 'counted SQL' for {@link dDBList::CountRecs()} to build the correct
+ * count query.
+ * Example:
+ * <code>
+ * ...
+ * $this->SetSelectSQL('SELECT product_id, SUM(amount) FROM sales');
+ * $this->SetCounterSQL('SUM(amount)');
+ * ...
+ * </code>
+ *
+ * {@link kDBList::CountRecs()} will replace the SELECT part with COUNT(*), SUM(amount) when counting records, which will give the accurate
+ * number of records. The number of records is used in list pagination
+ *
+ * @access public
+ * @param string
+ * @return void
+ */
+ function SetCountedSQL($sql)
+ {
+ $this->CountedSQL = $sql;
+ }
+
+ /**
+ * Counts the total number of records base on the query resulted from {@link kDBList::GetSelectSQL()}
+ *
+ * The method modifies the query to substitude SELECT part (fields listing) with COUNT(*).
+ * Special care should be applied when working with lists based on grouped queries, all aggregate function fields
+ * like SUM(), AVERAGE() etc. should be added to CountedSQL by using {@link kDBList::SetCountedSQL()}
+ *
+ * @access public
+ * @param string
+ * @return void
+ */
+ function CountRecs()
+ {
+ $q = $this->GetSelectSQL();
+ $counted_sql = '';
+ if ($this->hasCounted) {
+ $counted_sql = $this->GetCountedSQL();
+ $counted_sql = ", $counted_sql";
+ }
+
+ if ( preg_match("/DISTINCT(.*?)FROM(?!_)/is",$q,$regs ) )
+ $q = preg_replace("/^.*SELECT DISTINCT(.*?)FROM(?!_)/is", "SELECT COUNT(DISTINCT ".$regs[1].") AS count FROM", $q);
+ else
+ $q = preg_replace("/^.*SELECT(.*?)FROM(?!_)/is", "SELECT COUNT(*) AS count $counted_sql FROM ", $q);
+
+ if ($this->DisplayQueries) {
+ echo get_class($this)." Count SQL: $q<br>";
+ }
+
+ $this->RecordsCount = (int)$this->Conn->GetOne($q);
+ $this->hasCounted=true;
+ }
+
+ /**
+ * Queries the database with SQL resulted from {@link kDBList::GetSelectSQL()} and stores result in {@link kDBList::SelectRS}
+ *
+ * All the sorting, pagination, filtration of the list should be set prior to calling Query().
+ *
+ * @access public
+ * @param string
+ * @return void
+ */
+ function Query()
+ {
+ $q = $this->GetSelectSQL();
+ if ($this->DisplayQueries) {
+ echo get_class($this)." Query SQL: $q LIMIT ".$this->PerPage." OFFSET ".$this->Offset." Page: ".$this->Page."<br>";
+ }
+ //$rs = $this->Conn->SelectLimit($q, $this->PerPage, $this->Offset);
+
+ $sql = $q.' '.$this->Conn->getLimitClause($this->Offset,$this->PerPage);
+
+ $this->Records = $this->Conn->Query($sql);
+ $this->SelectedCount=count($this->Records);
+
+ if ($this->Records === false) {
+ //handle errors here
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Builds full select query except for LIMIT clause
+ *
+ * @access public
+ * @return string
+ */
+ function GetSelectSQL()
+ {
+ $q = parent::GetSelectSQL();
+
+ $where = $this->GetWhereClause();
+ $having = $this->GetHavingClause();
+ $order = $this->GetOrderClause();
+ $group = $this->GetGroupClause();
+
+ if (!empty($where)) $q .= ' WHERE ' . $where;
+ if (!empty($having)) $q .= ' HAVING ' . $having;
+ if (!empty($group)) $q .= ' GROUP BY ' . $group;
+ if (!empty($order)) $q .= ' ORDER BY ' . $order;
+
+ return $q;
+ }
+
+ /**
+ * Returns WHERE clause of the query
+ *
+ * @access public
+ * @return string
+ */
+ function GetWhereClause()
+ {
+ return '';
+ }
+
+ /**
+ * Returns HAVING clause of the query
+ *
+ * @access public
+ * @return string
+ */
+ function GetHavingClause()
+ {
+ return '';
+ }
+
+ /**
+ * Returns GROUP BY clause of the query
+ *
+ * @access public
+ * @return string
+ */
+ function GetGroupClause()
+ {
+ return '';
+ }
+
+ /**
+ * Adds order field to ORDER BY clause
+ *
+ * @access public
+ * @param string $field Field name
+ * @param string $direction Direction of ordering (asc|desc)
+ * @return void
+ */
+ function AddOrderField($field, $direction)
+ {
+ $this->OrderFields[] = Array($field, $direction);
+ }
+
+ /**
+ * Removes all order fields
+ *
+ * @access public
+ * @return void
+ */
+ function ClearOrderFields()
+ {
+ $this->OrderFields = Array();
+ }
+
+ /**
+ * Returns ORDER BY Clause of the query
+ *
+ * The method builds order by clause by iterating {@link kDBList::OrderFields} array and concatenating it.
+ *
+ * @access public
+ * @return string
+ */
+ function GetOrderClause()
+ {
+ $ret = '';
+ foreach ($this->OrderFields as $field) {
+ $ret .= $field[0] . ' ' . $field[1] . ',';
+ }
+ $ret = rtrim($ret, ',');
+ return $ret;
+ }
+
+ /**
+ * Description
+ *
+ * @access public
+ * @param string
+ * @return void
+ */
+ function GetDBField($name)
+ {
+ $row =& $this->getCurrentRecord();
+ return $row[$name];
+ }
+
+ function GetField($name)
+ {
+ return $this->GetDBField($name);
+ }
+
+
+ function &getCurrentRecord()
+ {
+ return $this->Records[$this->CurrentIndex];
+ }
+
+ /**
+ * Description
+ *
+ * @access public
+ * @param string
+ * @return void
+ */
+ function GoFirst()
+ {
+ $this->CurrentIndex=0;
+ }
+
+ /**
+ * Description
+ *
+ * @access public
+ * @return void
+ */
+ function GoNext()
+ {
+ $this->CurrentIndex++;
+ }
+
+ /**
+ * Description
+ *
+ * @access public
+ * @return bool
+ */
+ function EOL()
+ {
+ return ($this->CurrentIndex >= $this->SelectedCount);
+ }
+
+ /**
+ * Description
+ *
+ * @access public
+ * @param string
+ * @return void
+ */
+ function GetTotalPages()
+ {
+ if ($this->PerPage == -1) return 1;
+ $this->TotalPages = (($this->RecordsCount - ($this->RecordsCount % $this->PerPage)) / $this->PerPage) // integer part of division
+ + (($this->RecordsCount % $this->PerPage) != 0); // adds 1 if there is a reminder
+ return $this->TotalPages;
+ }
+
+ /**
+ * Sets number of records to query per page
+ *
+ * @access public
+ * @param int $per_page Number of records to display per page
+ * @return void
+ */
+ function SetPerPage($per_page)
+ {
+ $this->PerPage = $per_page;
+ }
+
+ /**
+ * Description
+ *
+ * @access public
+ * @param int $page
+ * @return void
+ */
+ function SetPage($page)
+ {
+ if ($this->PerPage == -1) {
+ $this->Page = 1;
+ return;
+ }
+ if ($page < 1) $page = 1;
+ $this->Offset = ($page-1)*$this->PerPage;
+ if ($this->Offset > $this->RecordsCount)
+ $this->SetPage(1);
+ else {
+ $this->Page = $page;
+ }
+ //$this->GoFirst();
+ }
+}
+
+?>
\ No newline at end of file
Property changes on: trunk/core/kernel/db/dblist.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/core/kernel/db/db_event_handler.php
===================================================================
--- trunk/core/kernel/db/db_event_handler.php (nonexistent)
+++ trunk/core/kernel/db/db_event_handler.php (revision 932)
@@ -0,0 +1,409 @@
+<?php
+
+ /**
+ * Note:
+ * 1. When adressing variables from submit containing
+ * Prefix_Special as part of their name use
+ * $event->getPrefixSpecial(true) instead of
+ * $event->Prefix_Special as usual. This is due PHP
+ * is converting "." symbols in variable names during
+ * submit info "_". $event->getPrefixSpecial optional
+ * 1st parameter returns correct corrent Prefix_Special
+ * for variables beeing submitted such way (e.g. variable
+ * name that will be converted by PHP: "users.read_only_id"
+ * will be submitted as "users_read_only_id".
+ *
+ * 2. When using $this->Application-LinkVar on variables submitted
+ * from form which contain $Prefix_Special then note 1st item. Example:
+ * LinkVar($event->getPrefixSpecial(true).'_varname',$event->Prefix_Special.'_varname')
+ *
+ */
+
+
+ /**
+ * EventHandler that is used to process
+ * any database related events
+ *
+ */
+ class kDBEventHandler extends kEventHandler {
+
+ /**
+ * Loads item only
+ *
+ * @param kEvent $event
+ * @access protected
+ */
+ function OnLoad(&$event)
+ {
+ $object =& $this->createObject(&$event);
+ $this->Application->SetVar($event->Prefix_Special.'_SaveEvent','OnUpdate');
+ $event->redirect=false;
+ }
+
+ /**
+ * Get's ID of item to be edited.
+ * Returns 1st id in case if many
+ * items were selected.
+ *
+ * @param kEvent $event
+ * @return int
+ */
+ function getPassedID(&$event)
+ {
+ $ret=$this->Application->GetVar($event->getPrefixSpecial().'_id');
+ if($ret===false)
+ {
+ $ids=$this->Application->GetVar($event->getPrefixSpecial().'_selected_ids');
+ $ids=explode(',',$ids);
+ if($ids) $ret=array_shift($ids);
+ }
+ return $ret;
+ }
+
+ /**
+ * Builds item (loads if needed)
+ *
+ * @param kEvent $event
+ * @access protected
+ */
+ function OnItemBuild(&$event)
+ {
+ $object =& $this->createObject(&$event);
+ $this->dbBuild(&$object,&$event);
+
+ $sql=$this->getSelectSQL($event,'OnItemPrepareQuery');
+ $object->setSelectSQL($sql);
+
+ // 1. set from config what needed
+ $fields = $this->Application->getUnitOption($event->Prefix,'Fields');
+ $object->setConfigFields( array_keys($fields) );
+
+ // 2. loads if allowed
+ $auto_load = $this->Application->getUnitOption($event->Prefix,'AutoLoad');
+ if($auto_load)
+ {
+ $id = $this->getPassedID(&$event);
+ $object->Load($id);
+ }
+ }
+
+ /**
+ * Builds list
+ *
+ * @param kEvent $event
+ * @access protected
+ */
+ function OnListBuild(&$event)
+ {
+ $event->setPseudoClass('_List');
+ $object =& $this->createObject(&$event);
+
+ $this->dbBuild(&$object,&$event);
+
+ $sql=$this->getSelectSQL($event,'OnListPrepareQuery');
+ $object->setSelectSQL($sql);
+
+ $t=$this->Application->GetVar('t');
+ $this->Application->StoreVar('redirect_to',$t);
+
+ $this->SetPagination(&$event);
+ $this->SetSorting(&$event);
+ }
+
+ /**
+ * Set's correct page for list
+ * based on data provided with event
+ *
+ * @param kEvent $event
+ * @access private
+ * @see OnListBuild
+ */
+ function SetPagination(&$event)
+ {
+ $per_page = $event->getEventParam('per_page');
+ if(!$per_page)
+ {
+ $per_page=$this->Application->RecallVar($event->Prefix_Special.'_PerPage');
+ if(!$per_page)
+ {
+ $per_page=10;
+ }
+ }
+
+ $event->setPseudoClass('_List');
+ $object =& $this->createObject(&$event);
+ $object->SetPerPage($per_page);
+ $object->CountRecs();
+
+ $object->SetPage( $this->Application->GetLinkedVar( $event->Prefix_Special.'_Page' ) );
+ }
+
+ /**
+ * Set's correct sorting for list
+ * based on data provided with event
+ *
+ * @param kEvent $event
+ * @access private
+ * @see OnListBuild
+ */
+ function SetSorting(&$event)
+ {
+ $event->setPseudoClass('_List');
+ $object =& $this->createObject(&$event);
+
+ $cur_sort1 = $this->Application->RecallVar($event->Prefix_Special.'_Sort1');
+ $cur_sort1_dir = $this->Application->RecallVar($event->Prefix_Special.'_Sort1_Dir');
+ $cur_sort2 = $this->Application->RecallVar($event->Prefix_Special.'_Sort2');
+ $cur_sort2_dir = $this->Application->RecallVar($event->Prefix_Special.'_Sort2_Dir');
+
+ //Use default if not specified
+ /*if ( $cur_sort1 === false || $cur_sort1_dir == false ) {
+ $cur_sort1 = $this->Application->ConfigOption($event->Prefix_Special.'_Sort1');
+ $cur_sort1_dir = $this->Application->ConfigOption($event->Prefix_Special.'_Sort1_Dir');
+ $cur_sort2 = $this->Application->ConfigOption($event->Prefix_Special.'_Sort2');
+ $cur_sort2_dir = $this->Application->ConfigOption($event->Prefix_Special.'_Sort2_Dir');
+ }*/
+
+ if($cur_sort1 != '' && $cur_sort1_dir != '')
+ {
+ $object->AddOrderField($cur_sort1, $cur_sort1_dir);
+ }
+ if($cur_sort2 != '' && $cur_sort2_dir != '')
+ {
+ $object->AddOrderField($cur_sort2, $cur_sort2_dir);
+ }
+ }
+
+ /**
+ * Some kind of filter processing stuff.
+ * Not in use by now
+ *
+ */
+ function AddFilters()
+ {
+
+ }
+
+ /**
+ * Set's new page for list
+ *
+ * @param kEvent $event
+ * @access protected
+ */
+ function OnSetPage(&$event)
+ {
+ $event->setPseudoClass('_List');
+ $object =& $this->createObject(&$event);
+ $new_page =& $this->Application->GetVar($event->Prefix_Special.'_page');
+ $object->SetPage($new_page);
+ }
+
+ /**
+ * Set's new sorting for list
+ *
+ * @param kEvent $event
+ * @access protected
+ */
+ function OnSetSorting(&$event)
+ {
+ $this->Application->LinkVar($event->getPrefixSpecial(true).'_Sort1',$event->Prefix_Special.'_Sort1');
+ $this->Application->LinkVar($event->getPrefixSpecial(true).'_Sort1_Dir',$event->Prefix_Special.'_Sort1_Dir');
+
+ //$event->setPseudoClass('_List');
+ //$object =& $this->createObject(&$event);
+ }
+
+ /**
+ * Common builder part for Item & List
+ *
+ * @param Object $object
+ * @access private
+ */
+ function dbBuild(&$object,&$event)
+ {
+ // set Item & List common parameters from config
+ $table = $this->Application->getUnitOption($event->Prefix,'TableName');
+ $object->setTableName($table);
+
+ $id_field = $this->Application->getUnitOption($event->Prefix,'IDField');
+ $object->setIDField($id_field);
+
+ // get selected ids from post & save them to session
+ $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
+ $ids=array_keys($items_info);
+ if($ids)
+ {
+ $this->Application->SetVar($event->getPrefixSpecial().'_selected_ids',implode(',',$ids));
+ }
+ $this->Application->LinkVar($event->getPrefixSpecial().'_selected_ids');
+
+ // set's any possible hidden fields needed for both Item & List
+ $current_event = $this->Application->GetVar($event->Prefix_Special.'_event');
+ $this->Application->setEvent($event->Prefix_Special,$current_event);
+ }
+
+ /**
+ * Returns select query for loading item/list
+ *
+ * @param kEvent $event
+ * @param string $event_name
+ * @return string
+ * @access protected
+ */
+ function getSelectSQL(&$event,$event_name)
+ {
+ $new_event =& $this->inheritEvent(&$event);
+ $new_event->Name=$event_name;
+ $this->Application->HandleEvent(&$new_event);
+ return $event->getEventParam('SQLQuery');
+ }
+
+ /**
+ * Creates needed sql query to load item,
+ * if no query is defined in config for
+ * special requested, then use default
+ * query
+ *
+ * @param kEvent $event
+ * @access protected
+ */
+ function OnItemPrepareQuery(&$event)
+ {
+ $sqls = $this->Application->getUnitOption($event->Prefix,'ItemSQLs');
+ $sql = isset($sqls[$event->Special])?$sqls[$event->Special]:$sqls[''];
+ $event->MasterEvent->setEventParam('SQLQuery',$sql);
+ }
+
+ /**
+ * Creates needed sql query to load list,
+ * if no query is defined in config for
+ * special requested, then use default
+ * query
+ *
+ * @param kEvent $event
+ * @access protected
+ */
+ function OnListPrepareQuery(&$event)
+ {
+ $sqls = $this->Application->getUnitOption($event->Prefix,'ListSQLs');
+ $sql = isset($sqls[$event->Special])?$sqls[$event->Special]:$sqls[''];
+ $event->MasterEvent->setEventParam('SQLQuery',$sql);
+ }
+
+ /**
+ * Creates new kDBItem
+ *
+ * @param kEvent $event
+ * @access protected
+ */
+ function OnCreate(&$event)
+ {
+ $this->Application->setUnitOption($this->getPrefixSpecial(),'AutoLoad',false);
+ $object =& $this->createObject(&$event);
+ $this->prepareObject(&$object,&$event);
+
+ $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
+ if($items_info) $field_values = array_shift($items_info);
+
+ $object->SetFieldsFromHash($field_values);
+ if( $object->Create() )
+ {
+ $event->status=erSUCCESS;
+ }
+ else
+ {
+ $event->status=erFATAL;
+ $event->redirect=false;
+ }
+ }
+
+ /**
+ * Updates kDBItem
+ *
+ * @param kEvent $event
+ * @access protected
+ */
+ function OnUpdate(&$event)
+ {
+ $this->Application->setUnitOption($this->getPrefixSpecial(),'AutoLoad',false);
+ $object =& $this->createObject(&$event);
+ $this->prepareObject(&$object,&$event);
+
+ $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
+ if($items_info)
+ {
+ foreach($items_info as $id => $field_values)
+ {
+ //$object->Load($id);
+ $object->SetFieldsFromHash($field_values);
+ if( $object->Update($id) )
+ {
+ $event->status=erSUCCESS;
+ }
+ else
+ {
+ $event->status=erFATAL;
+ $event->redirect=false;
+ break;
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Delete's kDBItem object
+ *
+ * @param kEvent $event
+ * @access protected
+ */
+ function OnDelete(&$event)
+ {
+ $this->Application->setUnitOption($this->getPrefixSpecial(),'AutoLoad',false);
+ $object =& $this->createObject(&$event);
+ $object->ID=$this->Application->GetVar($event->Prefix_Special.'_id');
+ if( $object->Delete() )
+ {
+ $event->status=erSUCCESS;
+ }
+ else
+ {
+ $event->status=erFATAL;
+ $event->redirect=false;
+ break;
+ }
+ }
+
+ /**
+ * Prepares new kDBItem object
+ *
+ * @param kEvent $event
+ * @access protected
+ */
+ function OnNew(&$event)
+ {
+ $this->Application->setUnitOption($this->getPrefixSpecial(),'AutoLoad',false);
+ $object =& $this->createObject(&$event);
+ $this->prepareObject(&$object,&$event);
+ $object->setID(0);
+ $this->Application->SetVar($event->Prefix_Special.'_SaveEvent','OnCreate');
+
+
+ $event->redirect=false;
+ }
+
+ /**
+ * Cancel's kDBItem Editing/Creation
+ *
+ * @param kEvent $event
+ * @access protected
+ */
+ function OnCancel(&$event)
+ {
+
+
+ }
+ }
+
+
+?>
\ No newline at end of file
Property changes on: trunk/core/kernel/db/db_event_handler.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/core/kernel/db/db_connection.php
===================================================================
--- trunk/core/kernel/db/db_connection.php (nonexistent)
+++ trunk/core/kernel/db/db_connection.php (revision 932)
@@ -0,0 +1,483 @@
+<?php
+
+ /**
+ * Multi database connection class
+ *
+ */
+ class DBConnection {
+
+ /**
+ * Current database type
+ *
+ * @var string
+ * @access private
+ */
+ var $dbType = 'mysql';
+ /**
+ * Created connection handle
+ *
+ * @var resource
+ * @access private
+ */
+ var $connectionID = null;
+ /**
+ * Handle of currenty processed recordset
+ *
+ * @var resource
+ * @access private
+ */
+ var $queryID = null;
+ /**
+ * DB type specific function mappings
+ *
+ * @var Array
+ * @access private
+ */
+ var $metaFunctions = Array();
+
+ /**
+ * Function to handle sql errors
+ *
+ * @var string
+ * @access private
+ */
+ var $errorHandler = '';
+
+ /**
+ * Error code
+ *
+ * @var int
+ * @access private
+ */
+ var $errorCode = 0;
+ /**
+ * Error message
+ *
+ * @var string
+ * @access private
+ */
+ var $errorMessage = '';
+
+ /**
+ * Defines if database connection
+ * operations should generate debug
+ * information
+ *
+ * @var bool
+ */
+ var $debugMode=false;
+
+ /**
+ * Initializes connection class with
+ * db type to used in future
+ *
+ * @param string $dbType
+ * @return DBConnection
+ * @access public
+ */
+ function DBConnection($dbType, $errorHandler = '')
+ {
+ $this->dbType = $dbType;
+ $this->initMetaFunctions();
+ if(!$errorHandler)
+ {
+ $this->errorHandler = Array(&$this,'handleError');
+ }
+ }
+
+ /**
+ * Set's custom error
+ *
+ * @param int $code
+ * @param string $msg
+ * @access public
+ */
+ function setError($code,$msg)
+ {
+ $this->errorCode=$code;
+ $this->errorMessage=$msg;
+ }
+
+ /**
+ * Checks if previous query execution
+ * raised an error.
+ *
+ * @return bool
+ * @access public
+ */
+ function hasError()
+ {
+ return !($this->errorCode == 0);
+ }
+
+ /**
+ * Caches function specific to requested
+ * db type
+ *
+ * @access private
+ */
+ function initMetaFunctions()
+ {
+ $ret = Array();
+ switch($this->dbType)
+ {
+ case 'mysql':
+ $ret = Array(); // only define functions, that name differs from "dbType_<meta_name>"
+
+ break;
+
+
+ }
+ $this->metaFunctions = $ret;
+ }
+
+ /**
+ * Get's function for specific db type
+ * based on it's meta name
+ *
+ * @param string $name
+ * @return string
+ * @access private
+ */
+ function getMetaFunction($name)
+ {
+ if( !isset($this->metaFunctions[$name]) )
+ {
+ if(function_exists($this->dbType.'_'.$name)) return $this->dbType.'_'.$name;
+ }
+ else
+ {
+ return $this->dbType.$name;
+ }
+ return false;
+ }
+
+
+ /**
+ * Try to connect to database server
+ * using specified parameters and set
+ * database to $db if connection made
+ *
+ * @param string $host
+ * @param string $user
+ * @param string $pass
+ * @param string $db
+ * @access public
+ */
+ function Connect($host,$user,$pass,$db)
+ {
+ $func = $this->getMetaFunction('connect');
+ $this->connectionID = $func($host,$user,$pass) or die('Can\'t connect to db');
+ if($this->connectionID)
+ {
+ $this->setDB($db);
+ $this->showError();
+ }
+ }
+
+ /**
+ * Shows error message from previous operation
+ * if it failed
+ *
+ * @access private
+ */
+ function showError($sql='')
+ {
+ $this->setError(0,''); // reset error
+ if($this->connectionID)
+ {
+ $func = $this->getMetaFunction('errno'); $this->errorCode = $func($this->connectionID);
+ if($this->hasError())
+ {
+ $func = $this->getMetaFunction('error'); $this->errorMessage = $func($this->connectionID);
+ if(is_array($this->errorHandler))
+ {
+ $func = $this->errorHandler[1];
+ $ret = $this->errorHandler[0]->$func($this->errorCode,$this->errorMessage,$sql);
+ }
+ else
+ {
+ $func = $this->errorHandler;
+ $ret = $func($this->errorCode,$this->errorMessage,$sql);
+ }
+ if(!$ret) exit;
+ }
+ }
+ }
+
+ /**
+ * Default error handler for sql errors
+ *
+ * @param int $code
+ * @param string $msg
+ * @param string $sql
+ * @return bool
+ * @access private
+ */
+ function handleError($code,$msg,$sql)
+ {
+ echo '<b>Processing SQL</b>: '.$sql.'<br>';
+ echo '<b>Error ('.$code.'):</b> '.$msg.'<br>';
+ return false;
+ }
+
+ /**
+ * Set's database name for connection
+ * to $new_name
+ *
+ * @param string $new_name
+ * @return bool
+ * @access public
+ */
+ function setDB($new_name)
+ {
+ if(!$this->connectionID) return false;
+ $func = $this->getMetaFunction('select_db');
+ return $func($new_name);
+ }
+
+ /**
+ * Returns first field of first line
+ * of recordset if query ok or false
+ * otherwise
+ *
+ * @param string $sql
+ * @return string
+ * @access public
+ */
+ function GetOne($sql)
+ {
+ $row = $this->GetRow($sql);
+ if(!$row) return false;
+
+ return array_shift($row);
+ }
+
+ /**
+ * Returns first row of recordset
+ * if query ok, false otherwise
+ *
+ * @param stirng $sql
+ * @return Array
+ * @access public
+ */
+ function GetRow($sql)
+ {
+ $sql .= ' '.$this->getLimitClause(0,1);
+ $ret = $this->Query($sql);
+ if(!$ret) return $ret;
+
+ return array_shift($ret);
+ }
+
+ /**
+ * Returns 1st column of recordset as
+ * one-dimensional array or false otherwise
+ * Optional parameter $key_field can be used
+ * to set field name to be used as resulting
+ * array key
+ *
+ * @param string $sql
+ * @param string $key_field
+ * @return Array
+ * @access public
+ */
+ function GetCol($sql, $key_field = null)
+ {
+ $rows = $this->Query($sql);
+ if(!$rows) return $rows;
+
+ $i = 0; $row_count = count($rows);
+ $ret = Array();
+ if(isset($key_field))
+ {
+ while ($i < $row_count)
+ {
+ $ret[$rows[$i][$key_field]] = array_shift($rows[$i]);
+ $i++;
+ }
+ }
+ else
+ {
+ while ($i < $row_count)
+ {
+ $ret[] = array_shift($rows[$i]);
+ $i++;
+ }
+ }
+ return $ret;
+ }
+
+ /**
+ * Queries db with $sql query supplied
+ * and returns rows selected if any, false
+ * otherwise. Optional parameter $key_field
+ * allows to set one of the query fields
+ * value as key in string array.
+ *
+ * @param string $sql
+ * @param string $key_field
+ * @return Array
+ */
+ function Query($sql,$key_field = null)
+ {
+ if($this->debugMode) return $this->debugQuery($sql,$key_field);
+ $query_func = $this->getMetaFunction('query');
+ $this->queryID = $query_func($sql,$this->connectionID);
+ if( is_resource($this->queryID) )
+ {
+ $ret = Array();
+ $fetch_func = $this->getMetaFunction('fetch_assoc');
+ if( isset($key_field) )
+ {
+ while( ($row = $fetch_func($this->queryID)) )
+ {
+ $ret[$row[$key_field]] = $row;
+ }
+ }
+ else
+ {
+ while( ($row = $fetch_func($this->queryID)) )
+ {
+ $ret[] = $row;
+ }
+ }
+ $this->Destroy();
+ return $ret;
+ }
+ $this->showError($sql);
+ return false;
+ }
+
+ function ChangeQuery($sql)
+ {
+ $this->Query($sql);
+ return $this->errorCode==0 ? true : false;
+ }
+
+ function debugQuery($sql, $key_field = null)
+ {
+ $query_func = $this->getMetaFunction('query');
+ $this->queryID = $query_func($sql,$this->connectionID);
+ if( is_resource($this->queryID) )
+ {
+ $ret = Array();
+ $fetch_func = $this->getMetaFunction('fetch_assoc');
+ if( isset($key_field) )
+ {
+ while( ($row = $fetch_func($this->queryID)) )
+ {
+ $ret[$row[$key_field]] = $row;
+ }
+ }
+ else
+ {
+ while( ($row = $fetch_func($this->queryID)) )
+ {
+ $ret[] = $row;
+ }
+ }
+ $this->Destroy();
+ return $ret;
+ }
+ $this->showError($sql);
+ return false;
+ }
+
+ /**
+ * Free memory used to hold recordset handle
+ *
+ * @access private
+ */
+ function Destroy()
+ {
+ if($this->queryID)
+ {
+ $free_func = $this->getMetaFunction('free_result');
+ $free_func($this->queryID);
+ $this->queryID = null;
+ }
+ }
+
+ /**
+ * Returns auto increment field value from
+ * insert like operation if any, zero otherwise
+ *
+ * @return int
+ * @access public
+ */
+ function getInsertID()
+ {
+ $func = $this->getMetaFunction('insert_id');
+ return $func($this->connectionID);
+ }
+
+ /**
+ * Returns row count affected by last query
+ *
+ * @return int
+ * @access public
+ */
+ function getAffectedRows()
+ {
+ $func = $this->getMetaFunction('affected_rows');
+ return $func($this->connectionID);
+ }
+
+ /**
+ * Returns LIMIT sql clause part for specific db
+ *
+ * @param int $offset
+ * @param int $rows
+ * @return string
+ * @access private
+ */
+ function getLimitClause($offset, $rows)
+ {
+ if(!($rows > 0)) return '';
+
+ switch ($this->dbType) {
+
+ default:
+ return 'LIMIT '.$offset.','.$rows;
+ break;
+ }
+ }
+
+ /**
+ * Correctly quotes a string so that all strings are escaped. We prefix and append
+ * to the string single-quotes.
+ * An example is $db->qstr("Don't bother",magic_quotes_runtime());
+ *
+ * @param s the string to quote
+ * @param [magic_quotes] if $s is GET/POST var, set to get_magic_quotes_gpc().
+ * This undoes the stupidity of magic quotes for GPC.
+ *
+ * @return quoted string to be sent back to database
+ */
+ function qstr($s,$magic_quotes=false)
+ {
+ $replace_quote = "\\'";
+ if (!$magic_quotes)
+ {
+ return "'".str_replace("'",$replace_quote,$s)."'";
+ }
+
+ // undo magic quotes for "
+ $s = str_replace('\\"','"',$s);
+ return "'$s'";
+ }
+
+
+ /**
+ * Returns last error message
+ *
+ * @return string
+ * @access public
+ */
+ function getErrorMsg()
+ {
+ return $this->errorMessage;
+ }
+ }
+?>
\ No newline at end of file
Property changes on: trunk/core/kernel/db/db_connection.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/core/kernel/db/dbitem.php
===================================================================
--- trunk/core/kernel/db/dbitem.php (nonexistent)
+++ trunk/core/kernel/db/dbitem.php (revision 932)
@@ -0,0 +1,294 @@
+<?php
+
+/**
+* DBItem
+*
+* Desciption
+* @package kernel4
+*/
+class kDBItem extends kDBBase {
+ /**
+ * Description
+ *
+ * @var array Associative array of current item' field values
+ * @access public
+ */
+ var $FieldValues;
+
+ /**
+ * Holds item' primary key value
+ *
+ * @var int Value of primary key field for current item
+ * @access public
+ */
+ var $ID;
+
+ /**
+ * Fields allowed to be set (from table + virtual)
+ *
+ * @var Array
+ * @access private
+ */
+ var $Fields=Array();
+
+ /**
+ * All virtual field names
+ *
+ * @var Array
+ * @access private
+ */
+ var $VirtualFields=Array();
+
+ /**
+ * Set's field names from table
+ * from config
+ *
+ * @param Array $fields
+ * @access public
+ */
+ function setConfigFields($fields)
+ {
+ $this->Fields=$fields;
+ }
+
+ /**
+ * Sets current item field value
+ * (applies formatting)
+ *
+ * @access public
+ * @param string $name Name of the field
+ * @param mixed $value Value to set the field to
+ * @return void
+ */
+ function SetField($name,$value)
+ {
+ $this->SetDBField($name,$value);
+ }
+
+ /**
+ * Sets current item field value
+ * (doesn't apply formatting)
+ *
+ * @access public
+ * @param string $name Name of the field
+ * @param mixed $value Value to set the field to
+ * @return void
+ */
+ function SetDBField($name,$value)
+ {
+ $this->FieldValues[$name] = $value;
+ }
+
+
+ /**
+ * Return current item' field value by field name
+ * (apply formatter)
+ *
+ * @access public
+ * @param string $name field name to return
+ * @return mixed
+ */
+ function GetField($name)
+ {
+ return $this->GetDBField($name);
+ }
+
+ /**
+ * Return current item' field value by field name
+ * (doesn't apply formatter)
+ *
+ * @access public
+ * @param string $name field name to return
+ * @return mixed
+ */
+ function GetDBField($name)
+ {
+ return $this->FieldValues[$name];
+ }
+
+ /**
+ * Sets item' fields corresponding to elements in passed $hash values.
+ *
+ * The function sets current item fields to values passed in $hash, by matching $hash keys with field names
+ * of current item. If current item' fields are unknown {@link kDBItem::PrepareFields()} is called before acutally setting the fields
+ *
+ * @access public
+ * @param Array $hash
+ * @return void
+ */
+ function SetFieldsFromHash($hash)
+ {
+ foreach ($hash as $field_name => $field_value)
+ {
+ if( eregi("^[0-9]+$", $field_name) || !in_array($field_name,$this->Fields) ) continue;
+ $this->SetField($field_name,$field_value);
+ }
+ }
+
+ /**
+ * Returns part of SQL WHERE clause identifing the record, ex. id = 25
+ *
+ * @access public
+ * @param string $method Child class may want to know who called GetKeyClause, Load(), Update(), Delete() send its names as method
+ * @return void
+ * @see kDBItem::Load()
+ * @see kDBItem::Update()
+ * @see kDBItem::Delete()
+ */
+ function GetKeyClause($method=null)
+ {
+ return $this->IDField.' = '.$this->Conn->qstr($this->ID);
+ }
+
+ /**
+ * Loads item from the database by given id
+ *
+ * @access public
+ * @param int $id Primery Key Id to load
+ * @param string $id_field_name Optional parameter to load item by given Id field
+ * @return bool True if item has been loaded, false otherwise
+ */
+ function Load($id, $id_field_name=null)
+ {
+ if (isset($id_field_name)) $this->SetIDField($id_field_name);
+
+ if (!isset($id)) return false;
+
+ $this->ID = $id;
+
+ $q = $this->GetSelectSQL().' WHERE '.$this->GetKeyClause('load');
+ if ($this->DisplayQueries) {
+ echo get_class($this)." Load SQL: $q<br>";
+ }
+ $this->FieldValues = $this->Conn->GetRow($q);
+
+ if ($this->FieldValues === false) {
+ //Error handling could be here
+ return false;
+ }
+ $this->setID($id);
+ return true;
+ }
+
+ /**
+ * Updates previously loaded record with current item' values
+ *
+ * @access public
+ * @param int Primery Key Id to update
+ * @return void
+ */
+ function Update($id=null)
+ {
+ if( isset($id) ) $this->ID=$id;
+ if( !isset($this->ID) ) return false;
+
+ // Validate before updating
+ if( !$this->Validate() ) return false;
+
+ //Nothing to update
+ if(!$this->FieldValues) return true;
+
+ $sql = sprintf('UPDATE %s SET ',$this->TableName);
+ foreach ($this->FieldValues as $field_name => $field_value)
+ {
+ if ( isset($this->VirtualFields[$field_name]) ) continue; //skipping 'virtual' field
+ if ($field_name == $this->IDField) continue; //skipping Primary Key
+
+ $real_field_name = eregi_replace("^.*\.", '',$field_name); //removing table names from field names
+
+ //Adding part of SET clause for current field, escaping data with ADODB' qstr
+ $sql.= sprintf('%s=%s, ',$real_field_name,$this->Conn->qstr($this->FieldValues[$field_name], 0));
+ }
+ $sql = ereg_replace(", $", '', $sql); //Removing last comma and space
+
+ $sql.= sprintf(' WHERE %s', $this->GetKeyClause('update')); //Adding WHERE clause with Primary Key
+
+ if ($this->DisplayQueries) echo "Sql: $sql<br>";
+
+ if ($this->Conn->ChangeQuery($sql) === false) { //Executing query and checking results
+ if ($this->DisplayQueries)
+ {
+ echo "Error executing statement: ".$adodbConnection->ErrorMsg()."<br>";
+ }
+ return false;
+ }
+ return true;
+ }
+
+ function Validate()
+ {
+ return true;
+ }
+
+ /**
+ * Creates a record in the database table with current item' values
+ *
+ * @access public
+ * @return void
+ */
+ function Create()
+ {
+ if(!$this->Validate()) //Validating fields before attempting to create record
+ return false;
+
+ $fields_sql = '';
+ $values_sql = '';
+ foreach ($this->FieldValues as $field_name => $field_value)
+ {
+ if ( isset($this->VirtualFields[$field_name]) ) continue; //skipping 'virtual' field
+
+ $fields_sql .= sprintf('%s, ',$field_name); //Adding field name to fields block of Insert statement
+ //Adding field' value to Values block of Insert statement, escaping it with ADODB' qstr
+ $values_sql .= sprintf('%s, ',$this->Conn->qstr($this->FieldValues[$field_name], 0));
+ }
+ //Cutting last commas and spaces
+ $fields_sql = ereg_replace(", $", '', $fields_sql);
+ $values_sql = ereg_replace(", $", '', $values_sql);
+ $sql = sprintf('INSERT INTO %s (%s) VALUES (%s)', $this->TableName, $fields_sql, $values_sql); //Formatting query
+
+ //Executing the query and checking the result
+ if ($this->Conn->ChangeQuery($sql) === false)
+ {
+ if($this->DisplayQueries)
+ {
+ echo "Error executing statement: ".$this->Conn->getErrorMsg().'<br>';
+ }
+ return false;
+ }
+ $this->setID( $this->Conn->getInsertID() );
+ //$this->SetInsertID(); //Setting Primary Key ($this->id) for futher using the object
+ return true;
+ }
+
+ /**
+ * Deletes the record from databse
+ *
+ * @access public
+ * @return void
+ */
+ function Delete()
+ {
+ $q = 'DELETE FROM '.$this->TableName.' WHERE '.$this->GetKeyClause('Delete');
+ if ($this->DisplayQueries)
+ {
+ echo get_class($this).' Delete SQL: '.$q.'<br>';
+ }
+ return $this->Conn->ChangeQuery($q);
+ }
+
+ /**
+ * Set's new ID for item
+ *
+ * @param int $new_id
+ * @access public
+ */
+ function setID($new_id)
+ {
+ $this->ID=$new_id;
+ $this->SetDBField($this->IDField,$new_id);
+ }
+}
+
+
+
+?>
\ No newline at end of file
Property changes on: trunk/core/kernel/db/dbitem.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/core/kernel/languages/phrases_cache.php
===================================================================
--- trunk/core/kernel/languages/phrases_cache.php (nonexistent)
+++ trunk/core/kernel/languages/phrases_cache.php (revision 932)
@@ -0,0 +1,92 @@
+<?php
+
+class PhrasesCache extends kDBBase {
+
+ var $Phrases = Array();
+ var $Ids;
+
+ var $LanguageId = 1;
+
+ function PhrasesCache($LanguageId=1)
+ {
+ parent::kDBBase();
+ $this->Phrases = Array();
+ $this->LanguageId = $LanguageId;
+ $this->LoadPhrases( $this->GetCachedIds() );
+ }
+
+ function GetCachedIds()
+ {
+ $query = sprintf("SELECT PhraseList FROM %s WHERE Template = %s",
+ 'PhraseCache',
+ $this->Conn->Qstr($this->Application->GetVar('t')));
+ $phrases_ids = $this->Conn->GetOne($query);
+ if ($phrases_ids === false) return Array();
+ return explode(',', $phrases_ids);
+ }
+
+ function LoadPhrases($ids)
+ {
+ if (!is_array($ids) || count($ids) == 0) return;
+ $query = sprintf("SELECT Translation,Phrase FROM %s WHERE LanguageId = %s AND PhraseId IN (%s)",
+ 'Phrase',
+ $this->LanguageId,
+ join(',', $ids));
+ $phrases = $this->Conn->GetCol($query,'Phrase');
+ foreach($phrases as $phrase => $tanslation)
+ {
+ $this->AddCachedPhrase(strtoupper($phrase), $tanslation);
+ }
+ $this->Ids = $ids;
+ }
+
+ function AddCachedPhrase($label, $value)
+ {
+ $label = strtoupper($label);
+ $this->Phrases[$label] = $value;
+ }
+
+ function UpdateCache()
+ {
+ if (!is_array($this->Ids) || count($Ids) == 0) return;
+ $query = sprintf("REPLACE %s (PhraseList, CacheDate, Template)
+ VALUES (%s, %s, %s)",
+ 'PhraseCache',
+ $this->Conn->Qstr(join(',', $this->Ids)),
+ mktime(),
+ $this->Conn->Qstr($this->Application->GetVar('t')));
+ $this->Conn->Query($query);
+ }
+
+ function GetPhrase($label)
+ {
+ $label = strtoupper($label);
+ if (array_key_exists($label, $this->Phrases))
+ return $this->Phrases[$label];
+
+ $this->LoadPhraseByLabel($label);
+ return $this->GetPhrase($label);
+ }
+
+ function LoadPhraseByLabel($label)
+ {
+ $query = sprintf("SELECT PhraseId, Translation FROM %s WHERE LanguageId = %s AND UPPER(Phrase) = UPPER(%s)",
+ Phrase,
+ $this->LanguageId,
+ $this->Conn->qstr($label));
+ $res = $this->Conn->GetRow($query);
+ if ($res === false || count($res) == 0) {
+ $this->AddCachedPhrase($label, '!'.$label.'!'); //add it as already cached, as long as we dont need to cache not found phrase
+ return false;
+ }
+
+ $this->Phrases[$label] = $res['Translation'];
+ array_push($this->Ids, $res['PhraseId']);
+ $this->Ids = array_unique ( $this->Ids ); //just to make sure
+ return true;
+ }
+
+}
+
+
+?>
\ No newline at end of file
Property changes on: trunk/core/kernel/languages/phrases_cache.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/core/kernel/startup.php
===================================================================
--- trunk/core/kernel/startup.php (nonexistent)
+++ trunk/core/kernel/startup.php (revision 932)
@@ -0,0 +1,50 @@
+<?php
+
+ini_set('memory_limit', '50M');
+
+safeDefine('INPORTAL_TAGS', true);
+
+define('DOC_ROOT', rtrim($_SERVER['DOCUMENT_ROOT'], '/'));
+define('BASE_PATH', $base_path = ereg_replace('/admin', '', ereg_replace(DOC_ROOT, '', FULL_PATH)));
+
+safeDefine( 'SERVER_NAME', $_SERVER['SERVER_NAME']);
+define( 'KERNEL_PATH', DOC_ROOT.BASE_PATH.'/kernel4');
+safeDefine( 'PROTOCOL', 'http://');
+define( 'MODULES_PATH', DOC_ROOT.BASE_PATH.'/modules');
+define( 'THEMES_PATH', ereg_replace(DOC_ROOT.BASE_PATH,'',FULL_PATH). ( defined('ADMIN') ? '/templates' : '/templates'));
+
+safeDefine('ENV_VAR_NAME','kenv');
+
+if( file_exists(FULL_PATH.'/debug.php') )
+{
+ include_once(FULL_PATH.'/debug.php');
+ if( defined('DEBUG_MODE')&&DEBUG_MODE )
+ {
+ // if debugging with ZDE, then don't override standart error handler
+ if( isset($_REQUEST['debug_host']) ) define('DBG_HANDLE_ERRORS',0);
+ include_once(KERNEL_PATH.'/utility/debugger.php');
+ }
+}
+
+include_once(KERNEL_PATH.'/db/db_connection.php');
+
+safeDefine('CUSTOM_UPLOAD_PATH', '/templates/images/custom/');
+
+include_once(KERNEL_PATH."/application.php");
+include_once(MODULES_PATH."/general/my_application.php");
+
+safeDefine('LOGIN_CONTROLLER', 'LoginController');
+safeDefine('USER_MODEL', 'User');
+
+function print_pre($data, $label='')
+{
+ echo '<b>',$label,'</b><br><pre>',print_r($data,true),'</pre>';
+ //echo var_dump($data);
+}
+
+function safeDefine($const_name, $const_value)
+{
+ if(!defined($const_name)) define($const_name,$const_value);
+}
+
+?>
\ No newline at end of file
Property changes on: trunk/core/kernel/startup.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/core/kernel/application.php
===================================================================
--- trunk/core/kernel/application.php (nonexistent)
+++ trunk/core/kernel/application.php (revision 932)
@@ -0,0 +1,779 @@
+<?php
+//include_once(KERNEL_PATH."/base.php");
+//include_once(KERNEL_PATH."/mvc/models/dbitem.php");
+//include_once(KERNEL_PATH."/mvc/models/dblist.php");
+
+
+
+include_once(KERNEL_PATH."/kbase.php");
+
+include_once(KERNEL_PATH.'/processors/tag_processor.php');
+include_once(KERNEL_PATH."/event_handler.php");
+
+include_once(KERNEL_PATH."/utility/factory.php");
+
+include_once(KERNEL_PATH."/utility/iterator.php");
+include_once(KERNEL_PATH."/languages/phrases_cache.php");
+
+include_once(KERNEL_PATH."/db/dblist.php");
+include_once(KERNEL_PATH."/db/dbitem.php");
+include_once(KERNEL_PATH."/db/db_tag_processor.php");
+
+
+include_once(KERNEL_PATH."/utility/event.php");
+
+$profiler = null;
+
+/**
+* Basic class for Kernel3-based Application
+*
+* This class is a Facade for any other class which needs to deal with Kernel3 framework.<br>
+* The class incapsulates the main run-cycle of the script, provide access to all other objects in the framework.<br>
+* <br>
+* The class is a singleton, which means that there could be only one instance of KernelApplication in the script.<br>
+* This could be guranteed by NOT calling the class constuctor directly, but rather calling KernelApplication::Instance() method,
+* which returns an instance of the application. The method gurantees that it will return exactly the same instance for any call.<br>
+* See singleton pattern by GOF.
+* @package kernel4
+*/
+
+class kApplication {
+
+ /**
+ * Holds internal TemplateParser object
+ * @access private
+ * @var TemplateParser
+ */
+ var $Parser;
+
+ var $Profiler;
+
+ /**
+ * Holds parser output buffer
+ * @access private
+ * @var string
+ */
+ var $HTML;
+
+ var $DocRoot;
+ var $BasePath;
+ var $KernelPath;
+ var $Server;
+
+ /**
+ * The main Factory used to create
+ * almost any class of kernel and
+ * modules
+ *
+ * @access private
+ * @var kFactory
+ */
+ var $Factory;
+
+ var $XMLFactory; // in use?
+
+ /**
+ * Holds all phrases used
+ * in code and template
+ *
+ * @var PhrasesCache
+ */
+ var $Phrases;
+
+ /**
+ * Holds connection to database
+ *
+ * @var DBConnection
+ */
+ var $DB;
+
+ /**
+ * Constucts KernelApplication - constructor is PRIVATE
+ *
+ * The constuructor of KernelApplication should NOT be called directly
+ * To create KernelApplication, call its Instance() method
+ * @see KerenelApplication::Instance
+ * @access private
+ */
+ function kApplication()
+ {
+ global $doc_root, $base_path, $kernel_path, $protocol, $server;
+ $this->DocRoot = $doc_root;
+ $this->BasePath = $base_path;
+ $this->KernelPath = $kernel_path;
+ $this->Protocol = $protocol;
+ $this->Server = $server;
+ }
+
+ /**
+ * Returns kApplication instance anywhere in the script.
+ *
+ * This method should be used to get single kApplication object instance anywhere in the
+ * Kernel-based application. The method is guranteed to return the SAME instance of kApplication.
+ * Anywhere in the script you could write:
+ * <code>
+ * $application =& kApplication::Instance();
+ * </code>
+ * or in an object:
+ * <code>
+ * $this->Application =& kApplication::Instance();
+ * </code>
+ * to get the instance of kApplication. Note that we call the Instance method as STATIC - directly from the class.
+ * To use descendand of standard kApplication class in your project you would need to define APPLICATION_CLASS constant
+ * BEFORE calling kApplication::Instance() for the first time. If APPLICATION_CLASS is not defined the method would
+ * create and return default KernelApplication instance.
+ * @static
+ * @access public
+ * @return kApplication
+ */
+ function &Instance()
+ {
+ static $instance = false;
+
+ if (!$instance) {
+ if (!defined('APPLICATION_CLASS')) define('APPLICATION_CLASS', 'kApplication');
+ $class = APPLICATION_CLASS;
+ $instance = new $class();
+ }
+ return $instance;
+ }
+
+ /**
+ * Initializes the Application
+ *
+ * Creates Utilites instance, HTTPQuery, Session, Profiler, TemplatesCache, Parser
+ * @access public
+ * @see HTTPQuery
+ * @see Session
+ * @see TemplatesCache
+ * @return void
+ */
+ function Init()
+ {
+ $this->DB = new DBConnection(SQL_TYPE);
+ $this->DB->Connect(SQL_SERVER, SQL_USER, SQL_PASS, SQL_DB);
+ $this->DB->debugMode = $this->isDebugMode();
+
+ $this->SetDefaultConstants();
+
+ setcookie('CookiesOn', 1, time()+600);
+
+ $this->Factory = new kFactory();
+
+ $this->registerDefaultClasses();
+
+ // to read configs before doing any recallObject
+ $config_reader =& $this->recallObject('kUnitConfigReader');
+
+ $this->Phrases =& new PhrasesCache($this->RecallVar('LanguageId', DEFAULT_LANGUAGE_ID));
+
+ $this->ValidateLogin(); // TODO: write that method
+ }
+
+ /**
+ * Registers default classes such as ItemController, GridController and LoginController
+ *
+ * Called automatically while initializing Application
+ * @access private
+ * @return void
+ */
+ function RegisterDefaultClasses()
+ {
+ $this->registerClass('Utilites',KERNEL_PATH.'/utility/utilities.php');
+ $this->registerClass('HTTPQuery',KERNEL_PATH.'/utility/http_query.php');
+ $this->registerClass('Session',KERNEL_PATH.'/session/session.php');
+ $this->registerClass('kEventManager',KERNEL_PATH.'/event_manager.php','EventManager');
+
+ $this->registerClass('kUnitConfigReader',KERNEL_PATH.'/utility/unit_config_reader.php');
+
+ $this->registerClass('Params',KERNEL_PATH.'/utility/params.php','kActions');
+ $this->registerClass('Configuration',KERNEL_PATH.'/utility/configuration.php');
+
+ $this->registerClass('TemplatesCache',KERNEL_PATH.'/parser/template.php');
+ $this->registerClass('TemplateParser',KERNEL_PATH.'/parser/template_parser.php');
+
+ $this->registerClass('MainProcessor', KERNEL_PATH.'/processors/main_processor.php','m_TagProcessor');
+
+ $this->registerClass('kDBList', KERNEL_PATH.'/db/dblist.php');
+ $this->registerClass('kDBItem', KERNEL_PATH.'/db/dbitem.php');
+ $this->registerClass('kDBEventHandler', KERNEL_PATH.'/db/db_event_handler.php');
+ $this->registerClass('kDBTagProcessor', KERNEL_PATH.'/db/db_tag_processor.php');
+
+ $this->registerClass('kTagProcessor', KERNEL_PATH.'/processors/tag_processor.php');
+
+ /*$this->RegisterClass('LoginController', KERNEL_PATH.'/users/login_controller.php');*/
+ }
+
+ /**
+ * Defines default constants if it's not defined before - in config.php
+ *
+ * Called automatically while initializing Application and defines:
+ * LOGIN_CONTROLLER, XML_FACTORY etc.
+ * @access private
+ * @return void
+ */
+ function SetDefaultConstants()
+ {
+ if (!defined('SERVER_NAME')) define('SERVER_NAME', $_SERVER['SERVER_NAME']);
+ if (!defined('LOGIN_CONTROLLER')) define('LOGIN_CONTROLLER', 'LoginController');
+ if (!defined('XML_FACTORY')) define('XML_FACTORY', 'XMLFactory');
+ if (!defined('ADMINS_LIST')) define('ADMINS_LIST', '/users/users.php');
+ if (!defined('USER_MODEL')) define('USER_MODEL', 'Users');
+ if (!defined('DEFAULT_LANGUAGE_ID')) define('DEFAULT_LANGUAGE_ID', 1);
+ }
+
+ /**
+ * Actually runs the parser against current template and stores parsing result
+ *
+ * This method gets t variable passed to the script, loads the template given in t variable and
+ * parses it. The result is store in {@link $this->HTML} property.
+ * @access public
+ * @return void
+ */
+ function Run()
+ {
+ $event_manager =& $this->recallObject('EventManager');
+ $event_manager->ProcessRequest();
+
+ $this->Parser =& $this->recallObject('TemplateParser');
+ $template_cache =& $this->recallObject('TemplatesCache');
+ $t = $this->GetVar('t');
+ $this->HTML = $this->Parser->Parse( $template_cache->GetTemplateBody($t) );
+ }
+
+ /**
+ * Send the parser results to browser
+ *
+ * Actually send everything stored in {@link $this->HTML}, to the browser by echoing it.
+ * @access public
+ * @return void
+ */
+ function Done()
+ {
+ //eval("?".">".$this->HTML);
+ echo $this->HTML;
+ $this->Phrases->UpdateCache();
+
+ $session =& $this->recallObject('Session');
+ $session->SaveData();
+ }
+
+ // Facade
+
+ /**
+ * Returns current session id (SID)
+ * @access public
+ * @return longint
+ */
+ function GetSID()
+ {
+ $session =& $this->recallObject('Session');
+ return $session->GetID();
+ }
+
+ function DestroySession()
+ {
+ $session =& $this->recallObject('Session');
+ $session->DestroySession();
+ }
+
+ /**
+ * Returns variable passed to the script as GET/POST/COOKIE
+ *
+ * @access public
+ * @param string $var Variable name
+ * @return mixed
+ */
+ function GetVar($var,$mode=FALSE_ON_NULL)
+ {
+ $http_query =& $this->recallObject('HTTPQuery');
+ return $http_query->Get($var,$mode);
+ }
+
+ /**
+ * Returns ALL variables passed to the script as GET/POST/COOKIE
+ *
+ * @access public
+ * @return array
+ */
+ function GetVars()
+ {
+ $http_query =& $this->recallObject('HTTPQuery');
+ return $http_query->GetParams();
+ }
+
+ /**
+ * Set the variable 'as it was passed to the script through GET/POST/COOKIE'
+ *
+ * This could be useful to set the variable when you know that
+ * other objects would relay on variable passed from GET/POST/COOKIE
+ * or you could use SetVar() / GetVar() pairs to pass the values between different objects.<br>
+ *
+ * This method is formerly known as $this->Session->SetProperty.
+ * @param string $var Variable name to set
+ * @param mixed $val Variable value
+ * @access public
+ * @return void
+ */
+ function SetVar($var,$val)
+ {
+ $http_query =& $this->recallObject('HTTPQuery');
+ $http_query->Set($var,$val);
+ }
+
+ function RemoveVar($var)
+ {
+ $session =& $this->recallObject('Session');
+ return $session->RemoveVar($var);
+ }
+
+ /**
+ * Returns session variable value
+ *
+ * Return value of $var variable stored in Session. An optional default value could be passed as second parameter.
+ *
+ * @see SimpleSession
+ * @access public
+ * @param string $var Variable name
+ * @param mixed $default Default value to return if no $var variable found in session
+ * @return mixed
+ */
+ function RecallVar($var,$default='')
+ {
+ $session =& $this->recallObject('Session');
+ return $session->RecallVar($var,$default);
+ }
+
+ /**
+ * Stores variable $val in session under name $var
+ *
+ * Use this method to store variable in session. Later this variable could be recalled.
+ * @see RecallVar
+ * @access public
+ * @param string $var Variable name
+ * @param mixed $val Variable value
+ */
+ function StoreVar($var, $val)
+ {
+ $session =& $this->recallObject('Session');
+ $session->StoreVar($var, $val);
+ }
+
+ function StoreVarDefault($var, $val)
+ {
+ $session =& $this->recallObject('Session');
+ $session->StoreVarDefault($var, $val);
+ }
+
+ /**
+ * Links HTTP Query variable with session variable
+ *
+ * If variable $var is passed in HTTP Query it is stored in session for later use. If it's not passed it's recalled from session.
+ * This method could be used for making sure that GetVar will return query or session value for given
+ * variable, when query variable should overwrite session (and be stored there for later use).<br>
+ * This could be used for passing item's ID into popup with multiple tab -
+ * in popup script you just need to call LinkVar('id', 'current_id') before first use of GetVar('id').
+ * After that you can be sure that GetVar('id') will return passed id or id passed earlier and stored in session
+ * @access public
+ * @param string $var HTTP Query (GPC) variable name
+ * @param mixed $ses_var Session variable name
+ * @param mixed $default Default variable value
+ */
+ function LinkVar($var, $ses_var=null, $default='')
+ {
+ if (!isset($ses_var)) $ses_var = $var;
+ if ($this->GetVar($var) !== false) {
+ $this->StoreVar($ses_var, $this->GetVar($var));
+ }
+ else
+ $this->SetVar($var, $this->RecallVar($ses_var, $default));
+ }
+
+ /**
+ * Returns variable from HTTP Query, or from session if not passed in HTTP Query
+ *
+ * The same as LinkVar, but also returns the variable value taken from HTTP Query if passed, or from session if not passed.
+ * Returns the default value if variable does not exist in session and was not passed in HTTP Query
+ *
+ * @see LinkVar
+ * @access public
+ * @param string $var HTTP Query (GPC) variable name
+ * @param mixed $ses_var Session variable name
+ * @param mixed $default Default variable value
+ * @return mixed
+ */
+ function GetLinkedVar($var, $ses_var=null, $default='')
+ {
+ if (!isset($ses_var)) $ses_var = $var;
+ $this->LinkVar($var, $ses_var, $default);
+ return $this->GetVar($var);
+ }
+
+ function ExtractByMask($array, $mask, $key_id=1, $ret_mode=1)
+ {
+ $utils =& $this->recallObject('Utilities');
+ return $utils->ExtractByMask($array, $mask, $key_id, $ret_mode);
+ }
+
+ function GetSelectedIDs($mask, $format)
+ {
+ $http_query =& $this->recallObject('HTTPQuery');
+ return $http_query->GetSelectedIDs($mask, $format);
+ }
+
+ function GetSelectedIDsArray($mask, $value_mask="%s,")
+ {
+ $http_query =& $this->recallObject('HTTPQuery');
+ return $http_query->GetSelectedIDsArray($mask, $value_mask);
+ }
+
+ /**
+ * Returns configurtion option
+ *
+ * @param string $option
+ * @return string
+ * @access public
+ */
+ function ConfigOption($option)
+ {
+ $config =& $this->recallObject('Configuration');
+ return $config->Get($option);
+ }
+
+ /**
+ * Sets configuration option
+ *
+ * @param string $option
+ * @param string $value
+ * @return bool
+ * @access public
+ */
+ function SetConfigOption($option,$value)
+ {
+ $config =& $this->recallObject('Configuration');
+ return $config->Set($option, $value);
+ }
+
+ function AddBlock($name, $tpl)
+ {
+ $this->cache[$name] = $tpl;
+ }
+
+ function SetTemplateBody($title, $body)
+ {
+ $this->Templates->SetTemplateBody($title, $body);
+ }
+
+ function ProcessTag($tag_data)
+ {
+ $a_tag = new Tag($tag_data, $this->Parser);
+ return $a_tag->DoProcessTag();
+ }
+
+ function &GetProcessor($prefix)
+ {
+ $this->KernelDie('GetProcessor is DEPRICATED, use recallObject');
+// return $this->Processors->GetProcessor($prefix, new Tag('empty', $this->Parser));
+ }
+
+
+ /* DEFINETLY NEEDS TO BE MOVED AWAY!!!!! */
+ var $email_body;
+ function Email($params)
+ {
+ $this->email_body = $this->ParseBlock($params);
+ $from = $this->GetVar('email_from');
+ $to = $this->GetVar('email_to');
+ $replay = $this->GetVar('email_replay');
+ if ( $replay == "" ) $replay = $from;
+ $subject = $this->GetVar('email_subject');
+ $charset = $this->GetVar('email_charset');
+ // $display = $this->GetVar('email_display');
+ $display = 0;
+ if (!isset($charset) || $charset == '') $charset = 'US-ASCII';
+ $mime = $this->GetVar('email_mime');
+
+ if ($mime == 'yes') {
+ $mime_mail = new MIMEMail($to, $from, $subject, $charset);
+ $mime_mail->mailbody($this->email_body);
+
+ if ($f_name = $this->GetVar('email_attach')) {
+ $full_path = DOC_ROOT.BASE_PATH.'/'.$f_name;
+ $data = '';
+ if(file_exists($full_path)) {
+ $fd = fopen($full_path, "r");
+ $data = fread($fd, filesize($full_path));
+ fclose($fd);
+ }
+ else exit;
+
+ $filename = $this->GetVar('email_attach_filename');
+ $type = $this->GetVar('email_attach_type');
+
+ $mime_mail->attachfile_raw($data, $filename, $type);
+ $mime_mail->send();
+ }
+ }
+ else {
+ $headers.="From: $from\n";
+ $headers.="Reply-To: $replay\n";
+ $headers.="Content-Type: text/html; charset=\"$charset\"\n";
+ if ( $display == 1 ) {
+ echo "<pre>";
+ echo " from : $from <br>";
+ echo " to : $to <br>";
+ echo " replay : $replay <br>";
+ echo " subject : $subject <br>";
+ echo " this->email_body : $this->email_body <br>";
+ echo " headers : $headers <br>";
+ echo "</pre>";
+ }
+ mail($to, $subject, $this->email_body, $headers);
+ }
+ }
+
+ /**
+ * Return ADODB Connection object
+ *
+ * Returns ADODB Connection object already connected to the project database, configurable in config.php
+ * @access public
+ * @return ADODBConnection
+ */
+ function &GetADODBConnection()
+ {
+ return $this->DB;
+ }
+
+ function ParseBlock($params,$pass_params=0)
+ {
+ return $this->Parser->ParseBlock($params,$pass_params);
+ }
+
+ function &GetXMLFactory()
+ {
+ return $this->XMLFactory;
+ }
+
+ /**
+ * Return href for template
+ *
+ * @access public
+ * @param string $t Template path
+ * @var string $prefix index.php prefix - could be blank, 'admin'
+ */
+ function HREF($t, $prefix='')
+ {
+ global $HTTP_SERVER_VARS;
+ if (defined('ADMIN') && $prefix == '') $prefix='/admin';
+ if (defined('ADMIN') && $prefix == '_FRONT_END_') $prefix = '';
+ $index_file = defined('INDEX_FILE') ? INDEX_FILE : 'index.php';
+ $t_path = !empty($t) ? 't='.$t : '';
+
+ $session =& $this->recallObject('Session');
+ $sid = $session->NeedQueryString()?$this->GetSID():'';
+
+ $ret = $this->BaseURL($prefix).$index_file.'?'.ENV_VAR_NAME.'='.$sid.':'.$t;
+
+ $t_pass=$this->GetVar('t_pass');
+ if($t_pass)
+ {
+ $ret.=':';
+ $pass_info=explode(',',$t_pass); // array( prefix[.special], prefix[.special] ...
+ foreach($pass_info as $pass_element)
+ {
+ list($prefix)=explode('.',$pass_element);
+ $query_vars = $this->getUnitOption($prefix,'QueryString');
+ if($query_vars)
+ {
+ $tmp_string=Array(0=>$pass_element);
+ foreach($query_vars as $index => $var_name)
+ {
+ $tmp_string[$index]=$this->GetVar($pass_element.'_'.$var_name);
+ }
+
+ $ret.=implode('-',$tmp_string);
+ }
+ }
+
+
+ }
+
+ return $ret;
+ }
+
+ function BaseURL($prefix='')
+ {
+ return PROTOCOL.SERVER_NAME.(defined('PORT')?':'.PORT : '').BASE_PATH.$prefix.'/';
+ }
+
+ function Redirect($t='', $params='', $prefix='')
+ {
+ if ($t == '') $t = $this->GetVar('t');
+ $location = $this->HREF($t, $prefix);
+ $a_location = $location;
+ $location = sprintf("Location: %s".($params ? "&" : '')."%s",$location, $params);
+ //echo " location : $location <br>";
+
+
+ if (headers_sent() != '') {
+ echo "<b>Debug output above!!!</b> Proceed to redirect: <a href=\"$a_location\">$a_location</a><br>";
+ }
+ else
+ header("$location");
+
+ $session =& $this->recallObject('Session');
+ $session->SaveData();
+ exit;
+ }
+
+ function UserError($msg)
+ {
+ error_reporting(E_ALL);
+ trigger_error($msg, E_USER_WARNING );
+ }
+
+ function Phrase($label)
+ {
+ if (ereg("^!.+!$", $label) > 0) {
+ $label = substr($label, 1, -1); //cut exclamation marks
+ }
+ return $this->Phrases->GetPhrase($label);
+ }
+
+ /**
+ * Validtates user in session if required
+ *
+ */
+ function ValidateLogin()
+ {
+ if (defined('LOGIN_REQUIRED'))
+ {
+ // Original Kostja call
+ //$login_controller =& $this->Factory->MakeClass(LOGIN_CONTROLLER, Array('model' => USER_MODEL, 'prefix' => 'login'));
+
+ // Call proposed by Alex
+ //$login_controller =& $this->RecallObject(LOGIN_CONTROLLER, Array('model' => USER_MODEL, 'prefix' => 'login'));
+
+ //$login_controller->CheckLogin();
+ }
+ }
+
+ function KernelDie($message) {
+ echo "<b>KernelApplication died</b>: $message<br>Debug backtrace follows:<br>";
+ print_pre(debug_backtrace());
+ echo "</pre>";
+ }
+
+ function trigerError($message,$error_type=E_USER_WARNING)
+ {
+ trigger_error($message,$error_type);
+ }
+
+ /**
+ * Allows to process any type of event
+ *
+ * @param kEvent $event
+ * @access public
+ */
+ function HandleEvent(&$event)
+ {
+ $event_manager =& $this->recallObject('EventManager');
+ $event_manager->HandleEvent(&$event);
+ }
+
+ /**
+ * Registers new class in the factory
+ *
+ * @param string $real_class
+ * @param string $file
+ * @param string $pseudo_class
+ * @access public
+ */
+ function registerClass($real_class,$file,$pseudo_class=null)
+ {
+ $this->Factory->registerClass($real_class,$file,$pseudo_class);
+ }
+
+ /**
+ * Returns object using params specified,
+ * creates it if is required
+ *
+ * @param string $name
+ * @param string $pseudo_class
+ * @param Array $event_params
+ * @return Object
+ */
+ function &recallObject($name,$pseudo_class=null,$event_params=Array())
+ {
+ return $this->Factory->getObject($name,$pseudo_class,$event_params);
+ }
+
+ /**
+ * Checks if application is in debug mode
+ *
+ * @return bool
+ * @access public
+ */
+ function isDebugMode()
+ {
+ return defined('DEBUG_MODE')&&DEBUG_MODE;
+ }
+
+ /**
+ * Reads unit (specified by $prefix)
+ * option specified by $option
+ *
+ * @param string $prefix
+ * @param string $option
+ * @return string
+ * @access public
+ */
+ function getUnitOption($prefix,$option)
+ {
+ $unit_config_reader =& $this->recallObject('kUnitConfigReader');
+ return $unit_config_reader->getUnitOption($prefix,$option);
+ }
+
+ /**
+ * Set's new unit option value
+ *
+ * @param string $prefix
+ * @param string $name
+ * @param string $value
+ * @access public
+ */
+ function setUnitOption($prefix,$option,$value)
+ {
+ $unit_config_reader =& $this->recallObject('kUnitConfigReader');
+ return $unit_config_reader->setUnitOption($prefix,$option,$value);
+ }
+
+ /**
+ * Splits any mixing of prefix and
+ * special into correct ones
+ *
+ * @param string $prefix_special
+ * @return Array
+ * @access public
+ */
+ function processPrefix($prefix_special)
+ {
+ return $this->Factory->processPrefix($prefix_special);
+ }
+
+ /**
+ * Set's new event for $prefix_special
+ * passed
+ *
+ * @param string $prefix_special
+ * @param string $event_name
+ * @access public
+ */
+ function setEvent($prefix_special,$event_name)
+ {
+ $event_manager =& $this->recallObject('EventManager');
+ $event_manager->setEvent($prefix_special,$event_name);
+ }
+}
+
+?>
\ No newline at end of file
Property changes on: trunk/core/kernel/application.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/core/kernel/kbase.php
===================================================================
--- trunk/core/kernel/kbase.php (nonexistent)
+++ trunk/core/kernel/kbase.php (revision 932)
@@ -0,0 +1,206 @@
+<?php
+/**
+* Base
+*
+* Desciption
+* @package kernel4
+*/
+class kBase {
+ /**
+ * Holds reference to global KernelApplication instance
+ * @access public
+ * @var kApplication
+ */
+ var $Application;
+
+ /**
+ * Prefix, that was used
+ * to create an object
+ *
+ * @var string
+ * @access public
+ */
+ var $Prefix='';
+
+ /**
+ * Special, that was used
+ * to create an object
+ *
+ * @var string
+ * @access public
+ */
+ var $Special='';
+
+ /**
+ * Set's prefix and special
+ *
+ * @param string $prefix
+ * @param string $special
+ * @access public
+ */
+ function Init($prefix,$special)
+ {
+ $prefix=explode('_',$prefix,2);
+ $this->Prefix=$prefix[0];
+ $this->Special=$special;
+ }
+
+ /**
+ * Returns joined prefix
+ * and special if any
+ *
+ * @return string
+ * @access protected
+ */
+ function getPrefixSpecial()
+ {
+ return rtrim($this->Prefix.'.'.$this->Special,'.');
+ }
+
+ /**
+ * Set's application
+ *
+ * @return kBase
+ * @access public
+ */
+ function kBase()
+ {
+ $this->Application =& kApplication::Instance();
+ }
+}
+
+class kDBBase extends kBase {
+ /**
+ * Description
+ *
+ * @var DBConnection
+ * @access public
+ */
+ var $Conn;
+
+ /**
+ * Description
+ *
+ * @var string Name of primary key field for the item
+ * @access public
+ */
+ var $IDField;
+
+ /**
+ * Holds SELECT, FROM, JOIN parts of SELECT query
+ *
+ * @var string
+ * @access public
+ */
+ var $SelectClause;
+
+ /**
+ * Display queries executed by the class
+ *
+ * @var bool
+ * @access public
+ */
+ var $DisplayQueries = false;
+
+ /**
+ * Object that holds all
+ * formatters created
+ *
+ * @var kItemFormatter
+ * @access private
+ */
+ var $ItemFormatter;
+
+ /**
+ * Description
+ *
+ * @var string Item' database table name, without prefix
+ * @access public
+ */
+ var $TableName;
+
+ function kDBBase()
+ {
+ parent::kBase();
+ $this->Conn =& $this->Application->GetADODBConnection();
+ }
+
+ /**
+ * Set current item' database table name
+ *
+ * @access public
+ * @param string $table_name
+ * @return void
+ */
+ function setTableName($table_name)
+ {
+ $this->TableName = $table_name;
+ }
+
+ /**
+ * Sets SELECT part of list' query
+ *
+ * @access public
+ * @param string $sql SELECT and FROM [JOIN] part of the query up to WHERE
+ * @return void
+ */
+ function SetSelectSQL($sql)
+ {
+ $this->SelectClause = $sql;
+ }
+
+ function GetSelectSQL()
+ {
+ return sprintf($this->SelectClause,$this->TableName);
+ }
+
+ /**
+ * Sets ID Field name used as primary key for loading items
+ *
+ * @access public
+ * @param string $field_name
+ * @return void
+ * @see kDBBase::IDField
+ */
+ function setIDField($field_name)
+ {
+ $this->IDField = $field_name;
+ }
+
+ /**
+ * Returns formatted field value
+ *
+ * @param string $field
+ * @return string
+ * @access public
+ */
+ function GetField($field)
+ {
+
+ }
+
+ /**
+ * Returns unformatted field value
+ *
+ * @param string $field
+ * @return string
+ * @access public
+ */
+ function GetDBField($field)
+ {
+
+ }
+
+ /**
+ * Returns ID of currently processed record
+ *
+ * @return int
+ * @access public
+ */
+ function GetID()
+ {
+ return $this->GetDBField($this->IDField);
+ }
+}
+
+?>
\ No newline at end of file
Property changes on: trunk/core/kernel/kbase.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/core/kernel/parser/template.php
===================================================================
--- trunk/core/kernel/parser/template.php (nonexistent)
+++ trunk/core/kernel/parser/template.php (revision 932)
@@ -0,0 +1,118 @@
+<?php
+
+class Template {
+ var $Body = '';
+ var $BasePath = '';
+ var $Filename = '';
+
+ function Template($base_path=null, $filename=null)
+ {
+ if ($this->SetBasePath($base_path)) {
+ if (isset($filename)) {
+ $this->Filename = $filename;
+ $this->LoadTemplate();
+ }
+ }
+ }
+
+ function SetBasePath($base_path=null)
+ {
+ if (isset($base_path)) {
+ $base_path = eregi_replace("/$", '', $base_path); //Cutting possible last slash
+ $this->BasePath = $base_path;
+ return true;
+ }
+ return false;
+ }
+
+ function GetFullPath()
+ {
+ return $this->BasePath.'/'.$this->Filename.'.tpl';
+ }
+
+ function LoadTemplate($silent=0)
+ {
+ $filename = $this->GetFullPath();
+ if(file_exists($filename)) {
+ $handle = fopen ($filename, "r");
+ $contents = fread ($handle, filesize ($filename));
+ $this->SetBody($contents);
+ fclose ($handle);
+ return true;
+ }
+ else {
+ if (!$silent) echo "<b>File or block not found: $filename ($filename)</b><br>";
+ return false;
+ }
+ }
+
+ function SetBody($body)
+ {
+ $this->Body = $body;
+ }
+
+ function GetBody()
+ {
+ return $this->Body;
+ }
+}
+
+class TemplatesCache extends kBase {
+ var $Templates = Array();
+ var $BasePath;
+
+ function TemplatesCache()
+ {
+ parent::kBase();
+ $this->BasePath = DOC_ROOT.BASE_PATH.THEMES_PATH;
+ }
+
+ function LoadTemplate($filename, $title=NULL)
+ {
+ $template =& new Template($this->BasePath, $filename);
+ if (!isset($title)) $title = $filename;
+ $this->SetTemplate($title, $template);
+ }
+
+ function SetTemplate($title, &$template)
+ {
+ $this->Templates[$title] = $template;
+ }
+
+ function &GetTemplate($title)
+ {
+ if (!isset($this->Templates[$title])) {
+ $this->LoadTemplate($title);
+ }
+ return $this->Templates[$title];
+ }
+
+ function GetTemplateBody($title)
+ {
+ $template =& $this->GetTemplate($title);
+ return $template->GetBody();
+ }
+
+ function SetTemplateBody($title, $body)
+ {
+ $template =& new Template();
+ $template->SetBody($body);
+ $this->SetTemplate($title, $template);
+ }
+
+ function ParseTemplate($template_name)
+ {
+ $Parser =& new TemplateParser($this->Application);
+ return $Parser->Parse( $this->GetTemplateBody($template_name) );
+ }
+
+ function TemplateExists($filename)
+ {
+ $template =& new Template($this->BasePath);
+ $template->Filename = $filename;
+ return $template->LoadTemplate(1) !== false;
+ }
+}
+
+
+?>
\ No newline at end of file
Property changes on: trunk/core/kernel/parser/template.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/core/kernel/parser/tags.php
===================================================================
--- trunk/core/kernel/parser/tags.php (nonexistent)
+++ trunk/core/kernel/parser/tags.php (revision 932)
@@ -0,0 +1,229 @@
+<?php
+
+global $kernel_path;
+include_once(KERNEL_PATH.'/parser/construct_tags.php');
+include_once(KERNEL_PATH.'/utility/params.php');
+
+define ('parse', 0);
+define ('skip', 1);
+define ('skip_tags', 2);
+
+class Tag extends kBase {
+ var $Processor;
+ var $Tag;
+ var $Params = Array();
+ var $NamedParams = Array();
+ var $NP;
+ var $Parser;
+ var $TagData = '';
+
+ function Tag($tag_data, &$parser, $inp_tag=0)
+ {
+ parent::kBase();
+ $this->Parser =& $parser;
+ $this->TagData = $tag_data;
+ if ($tag_data != '') $this->ParseTagData($tag_data);
+ $this->NP =& $this->NamedParams;
+ }
+
+ function CopyFrom(&$tag)
+ {
+ $this->Processor = $tag->Processor;
+ $this->Tag = $tag->Tag;
+ $this->TagData = $tag->TagData;
+ $this->Params = $tag->Params;
+ $this->NamedParams = $tag->NamedParams;
+ $this->Parser =& $tag->Parser;
+ }
+
+ function GetFullTag()
+ {
+ return '<%'.$this->TagData.'%>';
+ }
+
+ function RebuildTagData()
+ {
+ $res = $this->Processor.':'.$this->Tag.' ';
+ foreach ($this->NamedParams as $name => $value) {
+ $res .= "$name='$value' ";
+ }
+ return $res;
+ }
+
+ function ReplaceParams($tag_data)
+ {
+ //print_pre($this->Parser->Pattern, $tag_data);
+ if (is_array($this->Parser->Params)) {
+ $tag_data = preg_replace($this->Parser->Pattern, $this->Parser->Values, $tag_data);
+ }
+ //echo "got: $tag_data<br>";
+ return $tag_data;
+ }
+
+ function CmpParams($a, $b)
+ {
+ $a_len = strlen($a);
+ $b_len = strlen($b);
+ if ($a_len == $b_len) return 0;
+ return $a_len > $b_len ? -1 : 1;
+ }
+
+ function ReplaceLanguageTags($tag_data)
+ {
+ preg_match_all("(!(la|lu)[^!]+!)", $tag_data, $res, PREG_PATTERN_ORDER);
+ $language_tags = $res[0];
+ uasort($language_tags, array ("Tag", "CmpParams"));
+
+ $values = Array();
+ $i = 0;
+ foreach ($language_tags as $label) {
+ array_push($values, $this->Application->Phrase($label));
+ $language_tags[$i] = '/' . $language_tags[$i] . '/';
+ $i++;
+ }
+ $tag_data = preg_replace($language_tags, $values, $tag_data);
+ return $tag_data;
+ }
+
+ function ParseTagData($tag_data)
+ {
+ $tag_data = $this->ReplaceParams($tag_data) . ' ';
+ $tag_data = $this->ReplaceLanguageTags($tag_data);
+
+
+ list ($key_data, $params) = explode(' ', $tag_data, 2);
+ list($this->Processor, $this->Tag) = explode(':', $key_data);
+
+ if ($params != '') $this->ParseNamedParams($params);
+ }
+
+ function ParseNamedParams($params_str)
+ {
+ $params =& new Params($params_str);
+ $this->NamedParams = $params->_Params;
+ }
+
+ function GetParam($param)
+ {
+ if (isset($this->NP[$param]))
+ return $this->NP[$param];
+ else
+ return false;
+ }
+
+ function Process()
+ {
+ if ($this->Processor == 'm' || $this->Processor == 'm_TagProcessor') { //if we are procssing Main tags
+ if ($this->Tag == 'block') {
+ $tag =& new BlockTag('', $this->Parser);
+ $tag->CopyFrom($this);
+ $tag->Process();
+ }
+ elseif ($this->Parser->SkipMode == skip_tags) {
+ return;
+ }
+ elseif (
+ $this->Tag == 'if' ||
+ $this->Tag == 'ifnot' ||
+ $this->Tag == 'else' ||
+ $this->Tag == 'elseif'
+ ) {
+ $tag =& new ConstructTag('', $this->Parser);
+ $tag->CopyFrom($this);
+ $tag->Process();
+ }
+ elseif ($this->Tag == 'xml') {
+ $tag =& new XMLTag('', $this->Parser);
+ $tag->CopyFrom($this);
+ $tag->Process();
+ }
+ else {
+ if ($this->Parser->SkipMode == skip) return;
+ //if (!$this->ProcessMainTag()) //other main tags
+ $this->ProcessTag();
+ }
+ }
+ else { //normal tags - processors other than main
+ if ($this->Parser->SkipMode == skip_tags || $this->Parser->SkipMode == skip) return; //do not parse if we skipping tags
+ $this->ProcessTag();
+ //$this->Parser->AppendOutput('<b>'.$this->Tag.'</b>');
+ }
+ }
+
+ function DoProcessTag()
+ {
+ //$processor =& $this->Application->Processors->GetProcessor($this->Processor, $this);
+ $processor =& $this->Application->recallObject($this->Processor);
+ return $processor->ProcessTag($this);
+ }
+
+ function ProcessTag()
+ {
+ $o = $this->DoProcessTag();
+ if ($o !== false)
+ {
+ $this->Parser->AppendOutput($o);
+ }
+ else
+ {
+ echo "<b>Warning:</b> can't process tag ".$this->Tag."<br>";
+ }
+ }
+}
+
+
+// ################### TESTS ############################
+
+global $suite;
+if (isset($suite)) {
+ class TestTags extends TestCase {
+
+ function testTagParsing()
+ {
+ global $application;
+
+ $tag_data = "m:test param1=\"123\"";
+ $tag =& new Tag($tag_data, $application->Parser);
+ $this->assertEquals('m', $tag->Processor);
+ $this->assertEquals('test', $tag->Tag);
+ $this->assertEquals('123', $tag->GetParam('param1'));
+
+ $this->assertFalse($tag->GetParam('no_such_param'));
+ }
+
+ function testTagParamEscaping()
+ {
+ global $application;
+
+ $tag_data = "m:test escape1='-\"-' \t\t \n \t\n escape2=\"+\\\"+\" \n escape3='*\'*' escape4='=\='";
+ //$tag_data = "m:test escape1='-\"-' escape2=\"+\\\"+\" escape3='*\'*' escape4='=\='";
+ $tag =& new Tag($tag_data, $application->Parser);
+ $this->assertEquals('-"-', $tag->GetParam('escape1'));
+ $this->assertEquals('+"+', $tag->GetParam('escape2'));
+ $this->assertEquals("*'*", $tag->GetParam('escape3'));
+ $this->assertEquals('=\=', $tag->GetParam('escape4'));
+ }
+
+ function testTagParamSubstitution()
+ {
+ global $application;
+
+ $application->Parser->SetParams( Array(
+ 'prefix' => 'a_prefix',
+ 'tag' => 'a_tag',
+ 'param_name' => 'a_param_name',
+ 'param_value' => 'a_param_value'
+ )
+ );
+
+ $tag_data = '$prefix:$tag $param_name="$param_value"';
+ $tag =& new Tag($tag_data, $application->Parser);
+ $this->assertEquals('a_prefix', $tag->Processor);
+ $this->assertEquals('a_tag', $tag->Tag);
+ $this->assertEquals('a_param_value', $tag->GetParam('a_param_name'));
+ }
+ }
+ $suite->addTest(new TestSuite("TestTags"));
+}
+
+?>
\ No newline at end of file
Property changes on: trunk/core/kernel/parser/tags.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/core/kernel/parser/construct_tags.php
===================================================================
--- trunk/core/kernel/parser/construct_tags.php (nonexistent)
+++ trunk/core/kernel/parser/construct_tags.php (revision 932)
@@ -0,0 +1,268 @@
+<?php
+
+global $kernel_path;
+include_once(KERNEL_PATH.'/parser/tags.php');
+
+//Template language contruct tags (if, block...) which has opening and ending
+class ConstructTag extends Tag {
+ var $StopTag = '';
+ var $SkipMode = 0;
+ var $Logic = 0;
+
+
+ function SetStopTag($tag)
+ {
+ $this->StopTag = $tag;
+ }
+
+ function StoreSkipMode()
+ {
+ $this->SkipMode = $this->Parser->SkipMode;
+ }
+
+ function RestoreSkipMode()
+ {
+ $this->Parser->SetSkipMode($this->SkipMode);
+ }
+
+ function RestoreThisLevelSkipMode()
+ {
+ $this->SkipMode = $this->Parser->Recursion[$this->Parser->RecursionIndex]->SkipMode;
+ }
+
+ function SuggestSkipMode($mode)
+ {
+ if ($mode >= 1) //if we need to skip - always forcing it
+ $this->Parser->SetSkipMode($mode);
+ else { //if we need to turn of skipping
+ if ($this->SkipMode == parse) //check if initially skipping was off
+ $this->Parser->SetSkipMode(parse); //set it to off only then
+ }
+ }
+
+ function GetLogic()
+ {
+ $prefix = $this->GetParam('prefix');
+ $function = $this->GetParam('function');
+
+ if ($prefix !== false) {
+ $tag =& new Tag('', $this->Parser);
+ $tag->Processor = $prefix;
+ $tag->Tag = $function;
+ $tag->NamedParams = $this->NP;
+ $this->Logic = $tag->DoProcessTag();
+ // echo " this->Logic : ".$this->Logic."<br>";
+ }
+ else
+ $this->Logic = $function;
+ }
+
+ function Process()
+ {
+ switch ($this->Tag) {
+ case 'if':
+ case 'ifnot':
+ $this->GetLogic();
+
+ $this->SetStopTag('endif'); //This recursion level should end when 'endif' is found
+ $this->Parser->Recurve($this); //Saving current tag in parser recursion array
+ $this->StoreSkipMode(); //Storing initial SkipMode
+
+ if ($this->Logic) {
+ $this->SuggestSkipMode(parse); //suggest we parse it
+ }
+ else {
+ $this->SuggestSkipMode(skip); //suggest we don't parse it
+ }
+ break;
+ case 'elseif':
+ $if_logic = $this->Parser->Recursion[$this->Parser->RecursionIndex]->Logic;
+ if (!$if_logic) { //if IF or ELSEIF above have not worked
+ $this->GetLogic();
+
+ if ($this->Logic) { //ELSEIF should run
+ $this->Parser->Recursion[$this->Parser->RecursionIndex]->Logic = $this->Logic; //To escape running ELSE or ELSEIF below
+ $this->SuggestSkipMode(parse);
+ }
+ else { //ELSEIF should NOT run
+ $this->SuggestSkipMode(skip);
+ }
+ }
+ else //IF or ELSEIF above HAVE worked - this ELSEIF should NOT run
+ $this->SuggestSkipMode(skip);
+ break;
+ case 'else':
+ $if_logic = $this->Parser->Recursion[$this->Parser->RecursionIndex]->Logic;
+ $this->RestoreThisLevelSkipMode();
+ if (!$if_logic) { //IF was false - ELSE should run
+ $this->SuggestSkipMode(parse);
+ }
+ else { //IF was true - ELSE should not run
+ $this->SuggestSkipMode(skip);
+ }
+ break;
+ }
+ }
+
+ function CheckRecursion(&$tag)
+ {
+ if ($this->CheckEndRecursion($tag)) {
+ $this->RestoreSkipMode(); //Restoring original SkipMode
+ return true;
+ }
+ return false;
+ }
+
+ function CheckEndRecursion(&$tag)
+ {
+ return ($tag->Tag == $this->StopTag); //Tag matches StopTag we are waiting for to close current recursion
+ }
+}
+
+class BlockTag extends ConstructTag {
+ var $BlockName = '';
+ var $InsideBlock = 0;
+
+ function Process()
+ {
+ switch ($this->Tag) {
+ case 'block':
+ $this->SetStopTag('blockend'); //This recursion level should end when 'blockend' is found
+ $this->Parser->Recurve($this); //Saving current tag in parser recursion array
+ $this->Parser->SetBuffer('');
+ $this->BlockName = $this->NP['name']; //Stroing BlockName
+ $this->StoreSkipMode();
+ $this->SuggestSkipMode(skip_tags); //We need to skip tags from now
+ break;
+ }
+ }
+
+ function CheckRecursion(&$tag)
+ {
+ if (parent::CheckRecursion($tag)) { //if endtag matches (SkipMode would be restored then)
+ //Creating template from buffer
+ $template = new Template();
+ $template->SetBody($this->Parser->GetBuffer());
+
+ $templates_cache =& $this->Application->recallObject('TemplatesCache');
+
+ //Adding template to application' cache
+ $templates_cache->SetTemplate($this->BlockName,$template);
+ return true;
+ }
+ else {
+ // append the tag itself to the block - while in block, we check every tag to be 'blockend'
+ // if it is not - we need to append the tag to the buffer, which we'll parse later in 'parse_block'
+ if ($tag->Tag != 'block') {
+ $this->Parser->AppendOutput($tag->GetFullTag());
+ }
+ return false;
+ }
+ }
+}
+
+class XMLTag extends ConstructTag {
+ var $BlockName = '';
+
+ function Process()
+ {
+ switch ($this->Tag) {
+ case 'xml':
+ $this->SetStopTag('xmlend'); //This recursion level should end when 'blockend' is found
+ $this->Parser->Recurve($this); //Saving current tag in parser recursion array
+ $this->BlockName = $this->NP['name']; //Storing BlockName
+ $this->StoreSkipMode();
+ $this->SuggestSkipMode(skip_tags); //We need to skip tags from now
+ $this->Parser->SetBuffer('');
+ break;
+ }
+ }
+
+ function CheckRecursion(&$tag)
+ {
+ if (parent::CheckRecursion($tag)) { //if endtag matches (SkipMode would be restored then)
+ //Creating template from buffer
+ $template = new Template();
+ $template->SetBody($this->Parser->GetBuffer());
+
+ //Adding template to application' cache
+ $this->Parser->Application->Templates->SetTemplate(
+ $this->BlockName,
+ $template
+ );
+ $this->Parser->ParseXML($this->BlockName, $this->NP);
+ return true;
+ }
+ else {
+ if ($tag->Tag != 'xml') {
+ $this->Parser->AppendOutput($tag->GetFullTag());
+ }
+ return false;
+ }
+ }
+}
+
+class IterateTag extends ConstructTag {
+
+ function Process()
+ {
+ switch ($this->Tag) {
+ case 'iterate':
+ $this->SetStopTag('enditerate'); //This recursion level should end when 'blockend' is found
+ $this->Parser->Recurve($this); //Saving current tag in parser recursion array
+ $this->BlockName = $this->NP['block']; //Storing BlockName
+ $this->StoreSkipMode();
+ $this->SuggestSkipMode(skip_tags); //We need to skip tags from now
+ $this->Parser->SetBuffer('');
+ break;
+ }
+ }
+
+ function CheckRecursion(&$tag)
+ {
+ if (parent::CheckRecursion($tag)) { //if endtag matches (SkipMode would be restored then)
+ //Creating template from buffer
+ $template = new Template();
+ $template->SetBody($this->Parser->GetBuffer());
+
+ //Adding template to application' cache
+ $this->Parser->Application->Templates->SetTemplate(
+ $this->BlockName,
+ $template
+ );
+ $this->Parser->ParseXML($this->BlockName, $this->NP);
+ return true;
+ }
+ else {
+ if ($tag->Tag != 'xml') {
+ $this->Parser->AppendOutput($tag->GetFullTag());
+ }
+ return false;
+ }
+ }
+
+}
+
+global $suite;
+if (isset($suite)) {
+ class TestConstructTag extends TestCase {
+
+ function testIFLogic()
+ {
+ global $application;
+
+ $tag =& new ConstructTag('m:if prefix="m" function="true"', $application->Parser);
+ $tag->GetLogic();
+ $this->assertTrue($tag->Logic);
+
+
+ $tag =& new ConstructTag('m:if prefix="m" function="false"', $application->Parser);
+ $tag->GetLogic();
+ $this->assertFalse($tag->Logic);
+ }
+
+ }
+ $suite->addTest(new TestSuite("TestConstructTag"));
+}
+
+?>
\ No newline at end of file
Property changes on: trunk/core/kernel/parser/construct_tags.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/core/kernel/parser/template_parser.php
===================================================================
--- trunk/core/kernel/parser/template_parser.php (nonexistent)
+++ trunk/core/kernel/parser/template_parser.php (revision 932)
@@ -0,0 +1,232 @@
+<?php
+
+include_once(KERNEL_PATH.'/parser/tags.php');
+
+class TemplateParser extends kBase {
+ var $Template;
+ var $Output = '';
+ var $Position = 0;
+ var $LastPosition = 0;
+
+ var $Ses;
+ var $Recursion = Array();
+ var $RecursionIndex = 0;
+ var $SkipMode = 0;
+ var $Params = Array();
+ var $Pattern = Array();
+ var $ForSort = Array();
+ var $Values = Array();
+ var $Buffers = Array();
+
+ function TemplateParser()
+ {
+ parent::kBase();
+ $this->Ses =& $this->Application->recallObject('Session');
+ }
+
+ function AddParam($pattern, $value, $dont_sort=0)
+ {
+ $this->ForSort[] = Array($pattern, $value);
+ if (!$dont_sort) //used when mass-adding params, to escape sorting after every new param
+ $this->SortParams(); //but do sort by default!
+ }
+
+ //We need to sort params by its name length desc, so that params starting with same word get parsed correctly
+ function SortParams()
+ {
+ uasort($this->ForSort, array ("TemplateParser", "CmpParams"));
+ $this->Pattern = Array();
+ $this->Values = Array();
+ foreach($this->ForSort as $pair)
+ {
+ $this->Pattern[] = $pair[0];
+ $this->Values[] = $pair[1];
+ }
+ }
+
+ function CmpParams($a, $b)
+ {
+ $a_len = strlen($a[0]);
+ $b_len = strlen($b[0]);
+ if ($a_len == $b_len) return 0;
+ return $a_len > $b_len ? -1 : 1;
+ }
+
+ function SetParams($params)
+ {
+ if (!is_array($params)) $params = Array();
+ $this->Params = $params;
+ foreach ($params as $key => $val) {
+ $this->AddParam('/\$'.$key.'/', $val, 1); //Do not sort every time
+ }
+ $this->SortParams(); //Sort once after adding is done
+ }
+
+ function GetParam($name)
+ {
+ if (isset($this->Params[$name]))
+ return $this->Params[$name];
+ else
+ return false;
+ }
+
+ function SetParam($name, $value)
+ {
+ $this->Params[$name] = $value;
+ }
+
+ function SetBuffer($body)
+ {
+ $this->Buffers[$this->RecursionIndex] = $body;
+ }
+
+ function GetBuffer()
+ {
+ return $this->Buffers[$this->RecursionIndex];
+ }
+
+ function AppendBuffer($append)
+ {
+ $this->Buffers[$this->RecursionIndex] .= $append;
+ }
+
+ function AppendOutput($append)
+ {
+ if ($this->SkipMode == parse)
+ $this->Output .= $append; //append to Ouput only if we are parsing
+ elseif ($this->SkipMode == skip_tags) {
+ $this->AppendBuffer($append); //append to buffer if we are skipping tags
+ }
+ }
+
+ function FindTag()
+ {
+ $tagOpen = strpos($this->Template, '<%', $this->Position); //Finding tag start
+
+ $inp_tag = false;
+ $tagOpenLen = 2;
+
+ if ($tagOpen === false) { //If not tags left - adding all other data
+ $this->AppendOutput(substr($this->Template, $this->Position));
+ return false;
+ }
+
+ //Adding all data before tag open
+ $this->AppendOutput(substr($this->Template, $this->Position, $tagOpen - $this->Position));
+
+ //Finding tag end
+ $tagCloseLen = 2;
+ $tagClose = strpos($this->Template, "%>", $tagOpen);
+
+ if ($tagClose === false) die ("Can't find tag closing");
+
+ //Cutting out the tag itself
+ $tag = substr($this->Template, $tagOpen + $tagOpenLen, $tagClose - $tagOpen - $tagOpenLen);
+
+ //Seting current position right after the tag
+ $this->Position = $tagClose + $tagCloseLen;
+ return $tag;
+ }
+
+ function Parse($template)
+ {
+ $this->Template = $template;
+ $this->Position = 0;
+ $this->Output = '';
+
+ //While we have more tags
+ while ($tag_data = $this->FindTag())
+ {
+ //Create tag object from passed tag data
+ $tag =& new Tag($tag_data, $this);
+ if (!$this->CheckRecursion($tag)) //we do NOT process closing tags
+ {
+ $tag->Process();
+ }
+ }
+ return $this->Output;
+ }
+
+ function ParseBlock($params, $force_pass_params=0)
+ {
+ $BlockParser =& $this->Application->Factory->makeClass('TemplateParser');
+ if (isset($params['pass_params']) || $force_pass_params) {
+ $BlockParser->SetParams(array_merge($this->Params, $params));
+ }
+ else
+ $BlockParser->SetParams($params);
+ $this->Application->Parser =& $BlockParser;
+ if (!isset($params['name'])) die("<b>***Error: Block name not passed to ParseBlock</b><br>");
+ $templates_cache =& $this->Application->recallObject('TemplatesCache');
+ $o = $BlockParser->Parse(
+ $templates_cache->GetTemplateBody($params['name'])
+ );
+ $this->Application->Parser =& $this;
+ return $o;
+ }
+
+ function ParseXML($template, $params)
+ {
+ $templates_cache =& $this->Application->recallObject('TemplatesCache');
+ $xml = $templates_cache->GetTemplateBody($template);
+
+ $PreParser =& new TemplateParser();
+ $PreParser->SetParams($params);
+ $this->Application->Parser =& $PreParser;
+ $xml = $PreParser->Parse($xml);
+ $this->Application->Parser =& $this;
+ $XMLParser =& new XMLParser($params);
+ $this->AppendOutput($XMLParser->Parse($xml));
+ }
+
+ function Recurve(&$tag)
+ {
+ $this->Recursion[++$this->RecursionIndex] =& $tag;
+ }
+
+ function CheckRecursion(&$tag)
+ {
+ if ($this->RecursionIndex > 0) { //If we are inside the recursion
+ if ($this->Recursion[$this->RecursionIndex]->CheckRecursion($tag)) { //If we can close this recursion
+ unset($this->Recursion[$this->RecursionIndex--]); //unsetting current recursion level and decreasing it at the same time
+ return true; //we should inform not to process closing tag
+ }
+ }
+ return false;
+ }
+
+ function SetSkipMode($mode)
+ {
+ $this->SkipMode = $mode;
+ }
+}
+
+// ################### TESTS ############################
+
+global $suite;
+if (isset($suite)) {
+ class TestTemplateParser extends TestCase {
+ function testFindTag()
+ {
+ $parser =& new TemplateParser();
+ $parser->Template = 'before<%first_tag%>between<%second_tag%>after';
+ $this->assertEquals('first_tag', $parser->FindTag());
+ $this->assertEquals('second_tag', $parser->FindTag());
+ $parser->FindTag();
+ $this->assertEquals('beforebetweenafter', $parser->Output);
+ }
+
+ function testAppendOutput()
+ {
+ $parser =& new TemplateParser();
+ $parser->AppendOutput('1');
+ $this->assertEquals('1', $parser->Output);
+ $parser->SetSkipMode(skip);
+ $parser->AppendOutput('2');
+ $this->assertEquals('1', $parser->Output);
+ }
+ }
+ $suite->addTest(new TestSuite("TestTemplateParser"));
+}
+
+?>
\ No newline at end of file
Property changes on: trunk/core/kernel/parser/template_parser.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property

Event Timeline