From 21b4796a683192c3597f84585b98c60b42daab3a Mon Sep 17 00:00:00 2001 From: Ebersold Andre Date: Thu, 30 Dec 2021 14:08:37 +0100 Subject: [PATCH] Initial import from svn sydic-dev --- IXR_Library.inc | 818 +++++++++++++++++++++++++++++++++++++++ class.ActionResults.php | 31 ++ class.chiffre_lettre.php | 204 ++++++++++ class.controler.php | 20 + class.crontab.php | 31 ++ class.db.php | 160 ++++++++ class.feed.php | 369 ++++++++++++++++++ class.form.php | 261 +++++++++++++ class.fpdfdb.php | 165 ++++++++ class.http.Request.php | 169 ++++++++ class.images.php | 124 ++++++ class.json-rpc.php | 147 +++++++ class.logging.php | 68 ++++ class.menu.php | 169 ++++++++ class.nntp.php | 9 + class.notebook.php | 73 ++++ class.ofx.php | 108 ++++++ class.page.php | 246 ++++++++++++ class.router.php | 154 ++++++++ class.session.php | 182 +++++++++ class.sitemap.php | 59 +++ class.smtp.php | 671 ++++++++++++++++++++++++++++++++ class.validator.php | 73 ++++ iface.ActionResult.php | 12 + iface.Request.php | 45 +++ monofont.ttf | Bin 0 -> 41036 bytes utils.php | 18 + 27 files changed, 4386 insertions(+) create mode 100644 IXR_Library.inc create mode 100644 class.ActionResults.php create mode 100644 class.chiffre_lettre.php create mode 100644 class.controler.php create mode 100644 class.crontab.php create mode 100644 class.db.php create mode 100644 class.feed.php create mode 100644 class.form.php create mode 100644 class.fpdfdb.php create mode 100644 class.http.Request.php create mode 100644 class.images.php create mode 100644 class.json-rpc.php create mode 100644 class.logging.php create mode 100644 class.menu.php create mode 100644 class.nntp.php create mode 100644 class.notebook.php create mode 100644 class.ofx.php create mode 100644 class.page.php create mode 100644 class.router.php create mode 100644 class.session.php create mode 100644 class.sitemap.php create mode 100644 class.smtp.php create mode 100644 class.validator.php create mode 100644 iface.ActionResult.php create mode 100644 iface.Request.php create mode 100644 monofont.ttf create mode 100644 utils.php diff --git a/IXR_Library.inc b/IXR_Library.inc new file mode 100644 index 0000000..99f685e --- /dev/null +++ b/IXR_Library.inc @@ -0,0 +1,818 @@ + htmlspecialchars) + Site: http://scripts.incutio.com/xmlrpc/ + Manual: http://scripts.incutio.com/xmlrpc/manual.php + Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php +*/ + + +class IXR_Value { + var $data; + var $type; + function IXR_Value ($data, $type = false) { + $this->data = $data; + if (!$type) { + $type = $this->calculateType(); + } + $this->type = $type; + if ($type == 'struct') { + /* Turn all the values in the array in to new IXR_Value objects */ + foreach ($this->data as $key => $value) { + $this->data[$key] = new IXR_Value($value); + } + } + if ($type == 'array') { + for ($i = 0, $j = count($this->data); $i < $j; $i++) { + $this->data[$i] = new IXR_Value($this->data[$i]); + } + } + } + function calculateType() { + if ($this->data === true || $this->data === false) { + return 'boolean'; + } + if (is_integer($this->data)) { + return 'int'; + } + if (is_double($this->data)) { + return 'double'; + } + // Deal with IXR object types base64 and date + if (is_object($this->data) && is_a($this->data, 'IXR_Date')) { + return 'date'; + } + if (is_object($this->data) && is_a($this->data, 'IXR_Base64')) { + return 'base64'; + } + // If it is a normal PHP object convert it in to a struct + if (is_object($this->data)) { + + $this->data = get_object_vars($this->data); + return 'struct'; + } + if (!is_array($this->data)) { + return 'string'; + } + /* We have an array - is it an array or a struct ? */ + if ($this->isStruct($this->data)) { + return 'struct'; + } else { + return 'array'; + } + } + function getXml() { + /* Return XML for this value */ + switch ($this->type) { + case 'boolean': + return ''.(($this->data) ? '1' : '0').''; + break; + case 'int': + return ''.$this->data.''; + break; + case 'double': + return ''.$this->data.''; + break; + case 'string': + return ''.htmlspecialchars($this->data).''; + break; + case 'array': + $return = ''."\n"; + foreach ($this->data as $item) { + $return .= ' '.$item->getXml()."\n"; + } + $return .= ''; + return $return; + break; + case 'struct': + $return = ''."\n"; + foreach ($this->data as $name => $value) { + $return .= " $name"; + $return .= $value->getXml()."\n"; + } + $return .= ''; + return $return; + break; + case 'date': + case 'base64': + return $this->data->getXml(); + break; + } + return false; + } + function isStruct($array) { + /* Nasty function to check if an array is a struct or not */ + $expected = 0; + foreach ($array as $key => $value) { + if ((string)$key != (string)$expected) { + return true; + } + $expected++; + } + return false; + } +} + + +class IXR_Message { + var $message; + var $messageType; // methodCall / methodResponse / fault + var $faultCode; + var $faultString; + var $methodName; + var $params; + // Current variable stacks + var $_arraystructs = array(); // The stack used to keep track of the current array/struct + var $_arraystructstypes = array(); // Stack keeping track of if things are structs or array + var $_currentStructName = array(); // A stack as well + var $_param; + var $_value; + var $_currentTag; + var $_currentTagContents; + // The XML parser + var $_parser; + function IXR_Message ($message) { + $this->message = $message; + } + function parse() { + // first remove the XML declaration + $this->message = preg_replace('/<\?xml(.*)?\?'.'>/', '', $this->message); + if (trim($this->message) == '') { + return false; + } + $this->_parser = xml_parser_create(); + // Set XML parser to take the case of tags in to account + xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false); + // Set XML parser callback functions + xml_set_object($this->_parser, $this); + xml_set_element_handler($this->_parser, 'tag_open', 'tag_close'); + xml_set_character_data_handler($this->_parser, 'cdata'); + if (!xml_parse($this->_parser, $this->message)) { + /* die(sprintf('XML error: %s at line %d', + xml_error_string(xml_get_error_code($this->_parser)), + xml_get_current_line_number($this->_parser))); */ + return false; + } + xml_parser_free($this->_parser); + // Grab the error messages, if any + if ($this->messageType == 'fault') { + $this->faultCode = $this->params[0]['faultCode']; + $this->faultString = $this->params[0]['faultString']; + } + return true; + } + function tag_open($parser, $tag, $attr) { + $this->currentTag = $tag; + switch($tag) { + case 'methodCall': + case 'methodResponse': + case 'fault': + $this->messageType = $tag; + break; + /* Deal with stacks of arrays and structs */ + case 'data': // data is to all intents and puposes more interesting than array + $this->_arraystructstypes[] = 'array'; + $this->_arraystructs[] = array(); + break; + case 'struct': + $this->_arraystructstypes[] = 'struct'; + $this->_arraystructs[] = array(); + break; + } + } + function cdata($parser, $cdata) { + $this->_currentTagContents .= $cdata; + } + function tag_close($parser, $tag) { + $valueFlag = false; + switch($tag) { + case 'int': + case 'i4': + $value = (int)trim($this->_currentTagContents); + $this->_currentTagContents = ''; + $valueFlag = true; + break; + case 'double': + $value = (double)trim($this->_currentTagContents); + $this->_currentTagContents = ''; + $valueFlag = true; + break; + case 'string': + $value = (string)trim($this->_currentTagContents); + $this->_currentTagContents = ''; + $valueFlag = true; + break; + case 'dateTime.iso8601': + $value = new IXR_Date(trim($this->_currentTagContents)); + // $value = $iso->getTimestamp(); + $this->_currentTagContents = ''; + $valueFlag = true; + break; + case 'value': + // "If no type is indicated, the type is string." + if (trim($this->_currentTagContents) != '') { + $value = (string)$this->_currentTagContents; + $this->_currentTagContents = ''; + $valueFlag = true; + } + break; + case 'boolean': + $value = (boolean)trim($this->_currentTagContents); + $this->_currentTagContents = ''; + $valueFlag = true; + break; + case 'base64': + $value = base64_decode($this->_currentTagContents); + $this->_currentTagContents = ''; + $valueFlag = true; + break; + /* Deal with stacks of arrays and structs */ + case 'data': + case 'struct': + $value = array_pop($this->_arraystructs); + array_pop($this->_arraystructstypes); + $valueFlag = true; + break; + case 'member': + array_pop($this->_currentStructName); + break; + case 'name': + $this->_currentStructName[] = trim($this->_currentTagContents); + $this->_currentTagContents = ''; + break; + case 'methodName': + $this->methodName = trim($this->_currentTagContents); + $this->_currentTagContents = ''; + break; + } + if ($valueFlag) { + /* + if (!is_array($value) && !is_object($value)) { + $value = trim($value); + } + */ + if (count($this->_arraystructs) > 0) { + // Add value to struct or array + if ($this->_arraystructstypes[count($this->_arraystructstypes)-1] == 'struct') { + // Add to struct + $this->_arraystructs[count($this->_arraystructs)-1][$this->_currentStructName[count($this->_currentStructName)-1]] = $value; + } else { + // Add to array + $this->_arraystructs[count($this->_arraystructs)-1][] = $value; + } + } else { + // Just add as a paramater + $this->params[] = $value; + } + } + } +} + + +class IXR_Server { + var $data; + var $callbacks = array(); + var $message; + var $capabilities; + function IXR_Server($callbacks = false, $data = false) { + $this->setCapabilities(); + if ($callbacks) { + $this->callbacks = $callbacks; + } + $this->setCallbacks(); + $this->serve($data); + } + function serve($data = false) { + if (!$data) { + global $HTTP_RAW_POST_DATA; + if (!$HTTP_RAW_POST_DATA) { + die('XML-RPC server accepts POST requests only.'); + } + $data = $HTTP_RAW_POST_DATA; + } + $this->message = new IXR_Message($data); + if (!$this->message->parse()) { + $this->error(-32700, 'parse error. not well formed'); + } + if ($this->message->messageType != 'methodCall') { + $this->error(-32600, 'server error. invalid xml-rpc. not conforming to spec. Request must be a methodCall'); + } + $result = $this->call($this->message->methodName, $this->message->params); + // Is the result an error? + if (is_a($result, 'IXR_Error')) { + $this->error($result); + } + // Encode the result + $r = new IXR_Value($result); + $resultxml = $r->getXml(); + // Create the XML + $xml = << + + + + $resultxml + + + + + +EOD; + // Send it + $this->output($xml); + } + function call($methodname, $args) { + if (!$this->hasMethod($methodname)) { + return new IXR_Error(-32601, 'server error. requested method '.$methodname.' does not exist.'); + } + $method = $this->callbacks[$methodname]; + // Perform the callback and send the response + if (count($args) == 1) { + // If only one paramater just send that instead of the whole array + $args = $args[0]; + } + // Are we dealing with a function or a method? + if (substr($method, 0, 5) == 'this:') { + // It's a class method - check it exists + $method = substr($method, 5); + if (!method_exists($this, $method)) { + return new IXR_Error(-32601, 'server error. requested class method "'.$method.'" does not exist.'); + } + // Call the method + $result = $this->$method($args); + } else { + // It's a function - does it exist? + if (!function_exists($method)) { + return new IXR_Error(-32601, 'server error. requested function "'.$method.'" does not exist.'); + } + // Call the function + $result = $method($args); + } + return $result; + } + + function error($error, $message = false) { + // Accepts either an error object or an error code and message + if ($message && !is_object($error)) { + $error = new IXR_Error($error, $message); + } + $this->output($error->getXml()); + } + function output($xml) { + $xml = ''."\n".$xml; + $length = strlen($xml); + header('Connection: close'); + header('Content-Length: '.$length); + header('Content-Type: text/xml'); + header('Date: '.date('r')); + echo $xml; + exit; + } + function hasMethod($method) { + return in_array($method, array_keys($this->callbacks)); + } + function setCapabilities() { + // Initialises capabilities array + $this->capabilities = array( + 'xmlrpc' => array( + 'specUrl' => 'http://www.xmlrpc.com/spec', + 'specVersion' => 1 + ), + 'faults_interop' => array( + 'specUrl' => 'http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php', + 'specVersion' => 20010516 + ), + 'system.multicall' => array( + 'specUrl' => 'http://www.xmlrpc.com/discuss/msgReader$1208', + 'specVersion' => 1 + ), + ); + } + function getCapabilities($args) { + return $this->capabilities; + } + function setCallbacks() { + $this->callbacks['system.getCapabilities'] = 'this:getCapabilities'; + $this->callbacks['system.listMethods'] = 'this:listMethods'; + $this->callbacks['system.multicall'] = 'this:multiCall'; + } + function listMethods($args) { + // Returns a list of methods - uses array_reverse to ensure user defined + // methods are listed before server defined methods + return array_reverse(array_keys($this->callbacks)); + } + function multiCall($methodcalls) { + // See http://www.xmlrpc.com/discuss/msgReader$1208 + $return = array(); + foreach ($methodcalls as $call) { + $method = $call['methodName']; + $params = $call['params']; + if ($method == 'system.multicall') { + $result = new IXR_Error(-32600, 'Recursive calls to system.multicall are forbidden'); + } else { + $result = $this->call($method, $params); + } + if (is_a($result, 'IXR_Error')) { + $return[] = array( + 'faultCode' => $result->code, + 'faultString' => $result->message + ); + } else { + $return[] = array($result); + } + } + return $return; + } +} + +class IXR_Request { + var $method; + var $args; + var $xml; + function IXR_Request($method, $args) { + $this->method = $method; + $this->args = $args; + $this->xml = << + +{$this->method} + + +EOD; + foreach ($this->args as $arg) { + $this->xml .= ''; + $v = new IXR_Value($arg); + $this->xml .= $v->getXml(); + $this->xml .= "\n"; + } + $this->xml .= ''; + } + function getLength() { + return strlen($this->xml); + } + function getXml() { + return $this->xml; + } +} + + +class IXR_Client { + var $server; + var $port; + var $path; + var $useragent; + var $response; + var $message = false; + var $debug = false; + // Storage place for an error message + var $error = false; + function IXR_Client($server, $path = false, $port = 80) { + if (!$path) { + // Assume we have been given a URL instead + $bits = parse_url($server); + $this->server = $bits['host']; + $this->port = isset($bits['port']) ? $bits['port'] : 80; + $this->path = isset($bits['path']) ? $bits['path'] : '/'; + // Make absolutely sure we have a path + if (!$this->path) { + $this->path = '/'; + } + } else { + $this->server = $server; + $this->path = $path; + $this->port = $port; + } + $this->useragent = 'The Incutio XML-RPC PHP Library'; + } + function query() { + $args = func_get_args(); + $method = array_shift($args); + $request = new IXR_Request($method, $args); + $length = $request->getLength(); + $xml = $request->getXml(); + $r = "\r\n"; + $request = "POST {$this->path} HTTP/1.0$r"; + $request .= "Host: {$this->server}$r"; + $request .= "Content-Type: text/xml$r"; + $request .= "User-Agent: {$this->useragent}$r"; + $request .= "Content-length: {$length}$r$r"; + $request .= $xml; + // Now send the request + if ($this->debug) { + echo '
'.htmlspecialchars($request)."\n
\n\n"; + } + $fp = @fsockopen($this->server, $this->port); + if (!$fp) { + $this->error = new IXR_Error(-32300, 'transport error - could not open socket'); + return false; + } + fputs($fp, $request); + $contents = ''; + $gotFirstLine = false; + $gettingHeaders = true; + while (!feof($fp)) { + $line = fgets($fp, 4096); + if (!$gotFirstLine) { + // Check line for '200' + if (strstr($line, '200') === false) { + $this->error = new IXR_Error(-32300, 'transport error - HTTP status code was not 200'); + return false; + } + $gotFirstLine = true; + } + if (trim($line) == '') { + $gettingHeaders = false; + } + if (!$gettingHeaders) { + $contents .= trim($line)."\n"; + } + } + if ($this->debug) { + echo '
'.htmlspecialchars($contents)."\n
\n\n"; + } + // Now parse what we've got back + $this->message = new IXR_Message($contents); + if (!$this->message->parse()) { + // XML error + $this->error = new IXR_Error(-32700, 'parse error. not well formed'); + return false; + } + // Is the message a fault? + if ($this->message->messageType == 'fault') { + $this->error = new IXR_Error($this->message->faultCode, $this->message->faultString); + return false; + } + // Message must be OK + return true; + } + function getResponse() { + // methodResponses can only have one param - return that + return $this->message->params[0]; + } + function isError() { + return (is_object($this->error)); + } + function getErrorCode() { + return $this->error->code; + } + function getErrorMessage() { + return $this->error->message; + } +} + + +class IXR_Error { + var $code; + var $message; + function IXR_Error($code, $message) { + $this->code = $code; + $this->message = $message; + } + function getXml() { + $xml = << + + + + + faultCode + {$this->code} + + + faultString + {$this->message} + + + + + + +EOD; + return $xml; + } +} + + +class IXR_Date { + var $year; + var $month; + var $day; + var $hour; + var $minute; + var $second; + function IXR_Date($time) { + // $time can be a PHP timestamp or an ISO one + if (is_numeric($time)) { + $this->parseTimestamp($time); + } else { + $this->parseIso($time); + } + } + function parseTimestamp($timestamp) { + $this->year = date('Y', $timestamp); + $this->month = date('Y', $timestamp); + $this->day = date('Y', $timestamp); + $this->hour = date('H', $timestamp); + $this->minute = date('i', $timestamp); + $this->second = date('s', $timestamp); + } + function parseIso($iso) { + $this->year = substr($iso, 0, 4); + $this->month = substr($iso, 4, 2); + $this->day = substr($iso, 6, 2); + $this->hour = substr($iso, 9, 2); + $this->minute = substr($iso, 12, 2); + $this->second = substr($iso, 15, 2); + } + function getIso() { + return $this->year.$this->month.$this->day.'T'.$this->hour.':'.$this->minute.':'.$this->second; + } + function getXml() { + return ''.$this->getIso().''; + } + function getTimestamp() { + return mktime($this->hour, $this->minute, $this->second, $this->month, $this->day, $this->year); + } +} + + +class IXR_Base64 { + var $data; + function IXR_Base64($data) { + $this->data = $data; + } + function getXml() { + return ''.base64_encode($this->data).''; + } +} + + +class IXR_IntrospectionServer extends IXR_Server { + var $signatures; + var $help; + function IXR_IntrospectionServer() { + $this->setCallbacks(); + $this->setCapabilities(); + $this->capabilities['introspection'] = array( + 'specUrl' => 'http://xmlrpc.usefulinc.com/doc/reserved.html', + 'specVersion' => 1 + ); + $this->addCallback( + 'system.methodSignature', + 'this:methodSignature', + array('array', 'string'), + 'Returns an array describing the return type and required parameters of a method' + ); + $this->addCallback( + 'system.getCapabilities', + 'this:getCapabilities', + array('struct'), + 'Returns a struct describing the XML-RPC specifications supported by this server' + ); + $this->addCallback( + 'system.listMethods', + 'this:listMethods', + array('array'), + 'Returns an array of available methods on this server' + ); + $this->addCallback( + 'system.methodHelp', + 'this:methodHelp', + array('string', 'string'), + 'Returns a documentation string for the specified method' + ); + } + function addCallback($method, $callback, $args, $help) { + $this->callbacks[$method] = $callback; + $this->signatures[$method] = $args; + $this->help[$method] = $help; + } + function call($methodname, $args) { + // Make sure it's in an array + if ($args && !is_array($args)) { + $args = array($args); + } + // Over-rides default call method, adds signature check + if (!$this->hasMethod($methodname)) { + return new IXR_Error(-32601, 'server error. requested method "'.$this->message->methodName.'" not specified.'); + } + $method = $this->callbacks[$methodname]; + $signature = $this->signatures[$methodname]; + $returnType = array_shift($signature); + // Check the number of arguments + if (count($args) != count($signature)) { + // print 'Num of args: '.count($args).' Num in signature: '.count($signature); + return new IXR_Error(-32602, 'server error. wrong number of method parameters'); + } + // Check the argument types + $ok = true; + $argsbackup = $args; + for ($i = 0, $j = count($args); $i < $j; $i++) { + $arg = array_shift($args); + $type = array_shift($signature); + switch ($type) { + case 'int': + case 'i4': + if (is_array($arg) || !is_int($arg)) { + $ok = false; + } + break; + case 'base64': + case 'string': + if (!is_string($arg)) { + $ok = false; + } + break; + case 'boolean': + if ($arg !== false && $arg !== true) { + $ok = false; + } + break; + case 'float': + case 'double': + if (!is_float($arg)) { + $ok = false; + } + break; + case 'date': + case 'dateTime.iso8601': + if (!is_a($arg, 'IXR_Date')) { + $ok = false; + } + break; + } + if (!$ok) { + return new IXR_Error(-32602, 'server error. invalid method parameters'); + } + } + // It passed the test - run the "real" method call + return parent::call($methodname, $argsbackup); + } + function methodSignature($method) { + if (!$this->hasMethod($method)) { + return new IXR_Error(-32601, 'server error. requested method "'.$method.'" not specified.'); + } + // We should be returning an array of types + $types = $this->signatures[$method]; + $return = array(); + foreach ($types as $type) { + switch ($type) { + case 'string': + $return[] = 'string'; + break; + case 'int': + case 'i4': + $return[] = 42; + break; + case 'double': + $return[] = 3.1415; + break; + case 'dateTime.iso8601': + $return[] = new IXR_Date(time()); + break; + case 'boolean': + $return[] = true; + break; + case 'base64': + $return[] = new IXR_Base64('base64'); + break; + case 'array': + $return[] = array('array'); + break; + case 'struct': + $return[] = array('struct' => 'struct'); + break; + } + } + return $return; + } + function methodHelp($method) { + return $this->help[$method]; + } +} + + +class IXR_ClientMulticall extends IXR_Client { + var $calls = array(); + function IXR_ClientMulticall($server, $path = false, $port = 80) { + parent::IXR_Client($server, $path, $port); + $this->useragent = 'The Incutio XML-RPC PHP Library (multicall client)'; + } + function addCall() { + $args = func_get_args(); + $methodName = array_shift($args); + $struct = array( + 'methodName' => $methodName, + 'params' => $args + ); + $this->calls[] = $struct; + } + function query() { + // Prepare multicall, then call the parent::query() method + return parent::query('system.multicall', $this->calls); + } +} + +?> \ No newline at end of file diff --git a/class.ActionResults.php b/class.ActionResults.php new file mode 100644 index 0000000..6c91246 --- /dev/null +++ b/class.ActionResults.php @@ -0,0 +1,31 @@ +text = $_text; + } + + public function render() + { + echo $this->text; + } +} + +?> diff --git a/class.chiffre_lettre.php b/class.chiffre_lettre.php new file mode 100644 index 0000000..37553ca --- /dev/null +++ b/class.chiffre_lettre.php @@ -0,0 +1,204 @@ + 999999999999999) { + return "#TropGrand" ; + } + } + else { + if ($dblEnt > 9999999999999.99) { + return "#TropGrand" ; + } + } + switch($Devise) { + case 0 : + if ($byDec > 0) $strDev = " virgule" ; + break; + case 1 : + $strDev = " Euro" ; + if ($byDec > 0) $strCentimes = $strCentimes . " Cents" ; + break; + case 2 : + $strDev = " Dollar" ; + if ($byDec > 0) $strCentimes = $strCentimes . " Cent" ; + break; + } + if (($dblEnt > 1) && ($Devise != 0)) $strDev = $strDev . "s" ; + + $NumberLetter = $this->ConvNumEnt(floatval($dblEnt), $Langue) . $strDev . " " . $this->ConvNumDizaine($byDec, $Langue) . $strCentimes ; + return $NumberLetter; + } + + private function ConvNumEnt($Nombre, $Langue) { + $byNum=$iTmp=$dblReste='' ; + $StrTmp = ''; + $NumEnt='' ; + $iTmp = $Nombre - (intval($Nombre / 1000) * 1000) ; + $NumEnt = $this->ConvNumCent(intval($iTmp), $Langue) ; + $dblReste = intval($Nombre / 1000) ; + $iTmp = $dblReste - (intval($dblReste / 1000) * 1000) ; + $StrTmp = $this->ConvNumCent(intval($iTmp), $Langue) ; + switch($iTmp) { + case 0 : + break; + case 1 : + $StrTmp = "mille " ; + break; + default : + $StrTmp = $StrTmp . " mille " ; + } + $NumEnt = $StrTmp . $NumEnt ; + $dblReste = intval($dblReste / 1000) ; + $iTmp = $dblReste - (intval($dblReste / 1000) * 1000) ; + $StrTmp = $this->ConvNumCent(intval($iTmp), $Langue) ; + switch($iTmp) { + case 0 : + break; + case 1 : + $StrTmp = $StrTmp . " million " ; + break; + default : + $StrTmp = $StrTmp . " millions " ; + } + $NumEnt = $StrTmp . $NumEnt ; + $dblReste = intval($dblReste / 1000) ; + $iTmp = $dblReste - (intval($dblReste / 1000) * 1000) ; + $StrTmp = $this->ConvNumCent(intval($iTmp), $Langue) ; + switch($iTmp) { + case 0 : + break; + case 1 : + $StrTmp = $StrTmp . " milliard " ; + break; + default : + $StrTmp = $StrTmp . " milliards " ; + } + $NumEnt = $StrTmp . $NumEnt ; + $dblReste = intval($dblReste / 1000) ; + $iTmp = $dblReste - (intval($dblReste / 1000) * 1000) ; + $StrTmp = $this->ConvNumCent(intval($iTmp), $Langue) ; + switch($iTmp) { + case 0 : + break; + case 1 : + $StrTmp = $StrTmp . " billion " ; + break; + default : + $StrTmp = $StrTmp . " billions " ; + } + $NumEnt = $StrTmp . $NumEnt ; + return $NumEnt; + } + + private function ConvNumDizaine($Nombre, $Langue) { + $TabUnit=$TabDiz=''; + $byUnit=$byDiz='' ; + $strLiaison = '' ; + + $TabUnit = array("", "un", "deux", "trois", "quatre", "cinq", "six", "sept", + "huit", "neuf", "dix", "onze", "douze", "treize", "quatorze", "quinze", + "seize", "dix-sept", "dix-huit", "dix-neuf") ; + $TabDiz = array("", "", "vingt", "trente", "quarante", "cinquante", + "soixante", "soixante", "quatre-vingt", "quatre-vingt") ; + if ($Langue == 1) { + $TabDiz[7] = "septante" ; + $TabDiz[9] = "nonante" ; + } + else if ($Langue == 2) { + $TabDiz[7] = "septante" ; + $TabDiz[8] = "huitante" ; + $TabDiz[9] = "nonante" ; + } + $byDiz = intval($Nombre / 10) ; + $byUnit = $Nombre - ($byDiz * 10) ; + $strLiaison = "-" ; + if ($byUnit == 1) $strLiaison = " et " ; + switch($byDiz) { + case 0 : + $strLiaison = "" ; + break; + case 1 : + $byUnit = $byUnit + 10 ; + $strLiaison = "" ; + break; + case 7 : + if ($Langue == 0) $byUnit = $byUnit + 10 ; + break; + case 8 : + if ($Langue != 2) $strLiaison = "-" ; + break; + case 9 : + if ($Langue == 0) { + $byUnit = $byUnit + 10 ; + $strLiaison = "-" ; + } + break; + } + $NumDizaine = $TabDiz[$byDiz] ; + if ($byDiz == 8 && $Langue != 2 && $byUnit == 0) $NumDizaine = $NumDizaine . "s" ; + if ($TabUnit[$byUnit] != "") { + $NumDizaine = $NumDizaine . $strLiaison . $TabUnit[$byUnit] ; + } + else { + $NumDizaine = $NumDizaine ; + } + return $NumDizaine; + } + + private function ConvNumCent($Nombre, $Langue) { + $TabUnit='' ; + $byCent=$byReste='' ; + $strReste = '' ; + $NumCent=''; + $TabUnit = array("", "un", "deux", "trois", "quatre", "cinq", "six", "sept","huit", "neuf", "dix") ; + + $byCent = intval($Nombre / 100) ; + $byReste = $Nombre - ($byCent * 100) ; + $strReste = $this->ConvNumDizaine($byReste, $Langue); + switch($byCent) { + case 0 : + $NumCent = $strReste ; + break; + case 1 : + if ($byReste == 0) + $NumCent = "cent" ; + else + $NumCent = "cent " . $strReste ; + break; + default : + if ($byReste == 0) + $NumCent = $TabUnit[$byCent] . " cents" ; + else + $NumCent = $TabUnit[$byCent] . " cent " . $strReste ; + } + return $NumCent; + } +} +?> diff --git a/class.controler.php b/class.controler.php new file mode 100644 index 0000000..2349564 --- /dev/null +++ b/class.controler.php @@ -0,0 +1,20 @@ + diff --git a/class.crontab.php b/class.crontab.php new file mode 100644 index 0000000..c0369cd --- /dev/null +++ b/class.crontab.php @@ -0,0 +1,31 @@ +php." ".$job." 2>&1 >>NULL"; + file_put_content($this->filename,$data,FILE_APPEND); + } + function doQuarterly($job) { + $data = '30 7 15 2,5,8,11 * '.$this->php." ".$job." 2>&1 >>NULL"; + file_put_content($this->filename,$data,FILE_APPEND); + + } + function doJob($job) { + file_put_content($this->filename,$this->data,FILE_APPEND); + } + function commit() { + exec("crontab ".$filename,$output,$result); + if ($result === 0) { + } else { + log_error("Failed commit cron jobs"); + } + } +} +> diff --git a/class.db.php b/class.db.php new file mode 100644 index 0000000..5669200 --- /dev/null +++ b/class.db.php @@ -0,0 +1,160 @@ + 0 + , 'records' => array () + , 'result' => "" + ); + /* Request results */ + /* + * @brief Database interface + */ + function __construct($host,$user,$password,$dbname) { + /* Record version ... select VERSION();*/ + $this->mysqli = new mysqli($host,$user,$password,$dbname); + if (! $this->mysqli->connect_errno) { + $this->mysqli->set_charset('utf8'); + } + } + + function __destructor() { + $this->mysqli->close(); + } + + function insert_id() { + return $this->mysqli->insert_id; + } + /** + * @brief Some sanetizing + */ + function escape($values) { + if(is_array($values)) { + $values = array_map(array(&$this, 'escape'), $values); + } else { + /* Quote if not integer */ + if ( !is_numeric($values) || $values{0} == '0' ) { + $values = "\"" .filter_var($values,FILTER_SANITIZE_STRING) . "\""; + } + } + return $values; + } + + /** + * @brief seems to be used by church web site. I think + * this function should be deprecated + * + */ + function validateUser($user,$pwd ="") { + $u = $this->escape($user); + $p = $this->escape($pwd); + + $query="select * from annuaire_2004_pasteurs where mail = $u ;"; + $result =$this->mysqli->query($query); + if (!$result) { + //echo "Query failed: $query\n".mysql_error();; + echo "Query failed: $query\n".$this->mysqli->error; + return false; + } + + $result->close(); + return false; + } + + /** + * @brief simple query into json result. + * TODO: use mysqli driver instead of mysql + * + */ + function doQuery($sql,$count = "") { + $ident = Array('total_matches' => 0 + , 'records' => array () + , 'result' => "" + ); + if ($this->checkError("doQuery")) { + return $this->_r; + } + $result = $this->mysqli->query($sql); + if ( ! ($result === false) ) { + $i = 0; + while ($ident["records"][$i++] = $result->fetch_array(MYSQLI_ASSOC)) ; + + $result->close(); + + // Stating version 5 of mysql the queries can be more + // sofiticated + if ($count != "" ) { + $result = $this->query($count); + $row = $result->fetch_array(); + $ident["total_matches"] = (int)$row[0]; + $result->close(); + } + } + return $ident; + } + /** + */ + function doQueryI($sql,$count = "") { + $ident = Array('total_matches' => 0 , 'records' => array (),'result' => ""); + if ($this->checkError("doQueryI")) { + return $this->_r; + } + $qr = $this->mysqli->multi_query($sql); + $i = 0; + if (! ($qr === false )) + { + do { + if ($result = $this->mysqli->store_result()) { + while ($row = $result->fetch_row()) { + $ident["records"][$i++] = $row; + } + $result->free(); + } + + // Stating version 5 of mysql the queries can be more + // sofiticated + } while($this->mysqli->next_result()); + $ident['total_matches'] = $i; + } else { + error_log("doQuery ".$sql." Failed:".$this->mysqli->error,0); + $ident['result']="Failed :".$this->mysqli->error; + } + return $ident; + } + /** + * @brief Simple helper function to check Db status before any request. + * Always return the appropriate error message. + */ + function checkError($fct) { + if ($this->mysqli->connect_errno) { + $this->_r['result']="Failed :".$this->mysqli->error; + error_log("Db::".$fct." ".$this->mysqli->error); + return true; + } + return false; + } + /** + * @brief call this function after each request to check if an error + * happened or not. It's safer that checking the number of returned + * values. + */ + function checkQueryError() { + } + + function cleanDb() { + } +} + +?> diff --git a/class.feed.php b/class.feed.php new file mode 100644 index 0000000..bf851be --- /dev/null +++ b/class.feed.php @@ -0,0 +1,369 @@ +unix = $dateString; + return; + } + if (preg_match("~(?:(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),\\s+)?(\\d{1,2})\\s+([a-zA-Z]{3})\\s+(\\d{4})\\s+(\\d{2}):(\\d{2}):(\\d{2})\\s+(.*)~",$dateString,$matches)) { + $months = Array("Jan"=>1,"Feb"=>2,"Mar"=>3,"Apr"=>4,"May"=>5,"Jun"=>6,"Jul"=>7,"Aug"=>8,"Sep"=>9,"Oct"=>10,"Nov"=>11,"Dec"=>12); + $this->unix = mktime($matches[4],$matches[5],$matches[6],$months[$matches[2]],$matches[1],$matches[3]); + if (substr($matches[7],0,1)=='+' OR substr($matches[7],0,1)=='-') { + $tzOffset = (substr($matches[7],0,3) * 60 + substr($matches[7],-2)) * 60; + } else { + if (strlen($matches[7])==1) { + $oneHour = 3600; + $ord = ord($matches[7]); + if ($ord < ord("M")) { + $tzOffset = (ord("A") - $ord - 1) * $oneHour; + } elseif ($ord >= ord("M") AND $matches[7]!="Z") { + $tzOffset = ($ord - ord("M")) * $oneHour; + } elseif ($matches[7]=="Z") { + $tzOffset = 0; + } + } + switch ($matches[7]) { + case "UT": + case "GMT": $tzOffset = 0; + } + } + $this->unix += $tzOffset; + return; + } + if (preg_match("~(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})(.*)~",$dateString,$matches)) { + $this->unix = mktime($matches[4],$matches[5],$matches[6],$matches[2],$matches[3],$matches[1]); + if (substr($matches[7],0,1)=='+' OR substr($matches[7],0,1)=='-') { + $tzOffset = (substr($matches[7],0,3) * 60 + substr($matches[7],-2)) * 60; + } else { + if ($matches[7]=="Z") { + $tzOffset = 0; + } + } + $this->unix += $tzOffset; + return; + } + $this->unix = 0; + } + + /** + * Gets the date stored in this FeedDate as an RFC 822 date. + * + * @return a date in RFC 822 format + */ + function rfc822() { + //return gmdate("r",$this->unix); + $date = gmdate("D, d M Y H:i:s", $this->unix); + if (TIME_ZONE!="") $date .= " ".str_replace(":","",TIME_ZONE); + return $date; + } + + /** + * Gets the date stored in this FeedDate as an ISO 8601 date. + * + * @return a date in ISO 8601 (RFC 3339) format + */ + function iso8601() { + $date = gmdate("Y-m-d\TH:i:sO",$this->unix); + if (TIME_ZONE!="") $date = str_replace("+0000",TIME_ZONE,$date); + $date = substr($date,0,22) . ':' . substr($date,-2); + return $date; + } + + + /** + * Gets the date stored in this FeedDate as unix time stamp. + * + * @return a date as a unix time stamp + */ + function unix() { + return $this->unix; + } +} + + +/** + * \brief Feed Creator classs + * + */ +class FeedCreator { + var $title,$description,$link; + var $contentType = "application/xml"; + var $encoding = "utf-8"; + /** + * Should not be accessed + */ + var $items = Array(); + + /** + * \brief adds FeedItem to the feed; + * + * \param $item the FeedItem to be acced + */ + function addItem($item) { + $this->items[] = $item; + } + + /** + * \brief createFeed + */ + function createFeed() { + } + + /** + * + */ + function _redirect($filename) { + header("Content-Type:".$this->contentType."; charset=".$this->encoding."; filename=".basename($filename)); + header("Content-Disposition: inline; filename=".basename($filename)); + readfile($filename,"r"; + die(); + } + + /** + * + */ + function output() { + echo $this->createFeed(); + } +} + +/** + * RSSCreator091 is a FeedCreator that implements RSS 0.91 Spec, revision 3. + * + * @see http://my.netscape.com/publish/formats/rss-spec-0.91.html + * @since 1.3 + * @author Kai Blankenhorn + */ +class RSSCreator091 extends FeedCreator { + + /** + * Stores this RSS feed's version number. + * @access private + */ + var $RSSVersion; + + function RSSCreator091() { + $this->_setRSSVersion("0.91"); + $this->contentType = "application/rss+xml"; + } + + /** + * Sets this RSS feed's version number. + * @access private + */ + function _setRSSVersion($version) { + $this->RSSVersion = $version; + } + + /** + * Builds the RSS feed's text. The feed will be compliant to RDF Site Summary (RSS) 1.0. + * The feed will contain all items previously added in the same order. + * @return string the feed's complete text + */ + function createFeed() { + $feed = "encoding."\"?>\n"; + $feed.= $this->_createGeneratorComment(); + $feed.= $this->_createStylesheetReferences(); + $feed.= "RSSVersion."\">\n"; + $feed.= " \n"; + $feed.= " ".FeedCreator::iTrunc(htmlspecialchars($this->title),100)."\n"; + $this->descriptionTruncSize = 500; + $feed.= " ".$this->getDescription()."\n"; + $feed.= " ".$this->link."\n"; + $now = new FeedDate(); + $feed.= " ".htmlspecialchars($now->rfc822())."\n"; + $feed.= " ".FEEDCREATOR_VERSION."\n"; + + if ($this->image!=null) { + $feed.= " \n"; + $feed.= " ".$this->image->url."\n"; + $feed.= " ".FeedCreator::iTrunc(htmlspecialchars($this->image->title),100)."\n"; + $feed.= " ".$this->image->link."\n"; + if ($this->image->width!="") { + $feed.= " ".$this->image->width."\n"; + } + if ($this->image->height!="") { + $feed.= " ".$this->image->height."\n"; + } + if ($this->image->description!="") { + $feed.= " ".$this->image->getDescription()."\n"; + } + $feed.= " \n"; + } + if ($this->language!="") { + $feed.= " ".$this->language."\n"; + } + if ($this->copyright!="") { + $feed.= " ".FeedCreator::iTrunc(htmlspecialchars($this->copyright),100)."\n"; + } + if ($this->editor!="") { + $feed.= " ".FeedCreator::iTrunc(htmlspecialchars($this->editor),100)."\n"; + } + if ($this->webmaster!="") { + $feed.= " ".FeedCreator::iTrunc(htmlspecialchars($this->webmaster),100)."\n"; + } + if ($this->pubDate!="") { + $pubDate = new FeedDate($this->pubDate); + $feed.= " ".htmlspecialchars($pubDate->rfc822())."\n"; + } + if ($this->category!="") { + // Changed for DokuWiki: multiple categories are possible + if(is_array($this->category)) foreach($this->category as $cat){ + $feed.= " ".htmlspecialchars($cat)."\n"; + }else{ + $feed.= " ".htmlspecialchars($this->category)."\n"; + } + } + if ($this->docs!="") { + $feed.= " ".FeedCreator::iTrunc(htmlspecialchars($this->docs),500)."\n"; + } + if ($this->ttl!="") { + $feed.= " ".htmlspecialchars($this->ttl)."\n"; + } + if ($this->rating!="") { + $feed.= " ".FeedCreator::iTrunc(htmlspecialchars($this->rating),500)."\n"; + } + if ($this->skipHours!="") { + $feed.= " ".htmlspecialchars($this->skipHours)."\n"; + } + if ($this->skipDays!="") { + $feed.= " ".htmlspecialchars($this->skipDays)."\n"; + } + $feed.= $this->_createAdditionalElements($this->additionalElements, " "); + + for ($i=0;$iitems);$i++) { + $feed.= " \n"; + $feed.= " ".FeedCreator::iTrunc(htmlspecialchars(strip_tags($this->items[$i]->title)),100)."\n"; + $feed.= " ".htmlspecialchars($this->items[$i]->link)."\n"; + $feed.= " ".$this->items[$i]->getDescription()."\n"; + + if ($this->items[$i]->author!="") { + $feed.= " ".htmlspecialchars($this->items[$i]->author)."\n"; + } + /* + // on hold + if ($this->items[$i]->source!="") { + $feed.= " ".htmlspecialchars($this->items[$i]->source)."\n"; + } + */ + if ($this->items[$i]->category!="") { + // Changed for DokuWiki: multiple categories are possible + if(is_array($this->items[$i]->category)) foreach($this->items[$i]->category as $cat){ + $feed.= " ".htmlspecialchars($cat)."\n"; + }else{ + $feed.= " ".htmlspecialchars($this->items[$i]->category)."\n"; + } + } + + if ($this->items[$i]->comments!="") { + $feed.= " ".htmlspecialchars($this->items[$i]->comments)."\n"; + } + if ($this->items[$i]->date!="") { + $itemDate = new FeedDate($this->items[$i]->date); + $feed.= " ".htmlspecialchars($itemDate->rfc822())."\n"; + } + if ($this->items[$i]->guid!="") { + $feed.= " ".htmlspecialchars($this->items[$i]->guid)."\n"; + } + $feed.= $this->_createAdditionalElements($this->items[$i]->additionalElements, " "); + + if ($this->RSSVersion == "2.0" && $this->items[$i]->enclosure != NULL) + { + $feed.= " items[$i]->enclosure->url; + $feed.= "\" length=\""; + $feed.= $this->items[$i]->enclosure->length; + $feed.= "\" type=\""; + $feed.= $this->items[$i]->enclosure->type; + $feed.= "\"/>\n"; + } + + + + $feed.= " \n"; + } + + $feed.= " \n"; + $feed.= "\n"; + return $feed; + } +} + + + +/** + * RSSCreator20 is a FeedCreator that implements RDF Site Summary (RSS) 2.0. + * + * @see http://backend.userland.com/rss + * @since 1.3 + * @author Kai Blankenhorn + */ +class RSSCreator20 extends RSSCreator091 { + + function RSSCreator20() { + parent::_setRSSVersion("2.0"); + } + +} + + +/** + vim:et:ts=4:sw=4:enc=utf-8: + */ +?> diff --git a/class.form.php b/class.form.php new file mode 100644 index 0000000..9a9aa5d --- /dev/null +++ b/class.form.php @@ -0,0 +1,261 @@ +name = $name; + $this->id = $id; + $this->value= $value; + $this->label= $label; + $this->icon = ""; + } + function showLabel() { + if ($this->type == "hidden") + return; + if ($this->label != "") { + echo ""; + } + } + + function show() + { + $this->showLabel(); + if ( ! empty ($this->icon) ) { + echo "\n"; + } + echo "onClick != "") { + echo " onclick='".$this->onClick."' "; + } + if ($this->placeholder != "") { + echo " placeholder='".$this->placeholder."' "; + } + if ($this->class != "") { + echo " class='".$this->class."' "; + } + echo " name='".$this->name."' value='".$this->value."' id='".$this->name."'>\n"; + if ( !empty($this->icon)) { + echo "icon."\">\n"; + } + } + function setIcon($_i="") {$this->icon = $_i;} + function setClass($class= "") { $this->class = $class;} + function setWidth($l,$i) {$this->lWidth=$l;$this->iWith=$i;} + function setSize($s,$ml=0) {$this->iSize = $s;} +} + +/** + * @brief + * + * + */ +class FormInputText extends FormInput{ + function FormInputText($name,$value,$label="",$id="") { + parent::FormInput($name,$value,$label,$id); + $this->type="text"; + } +} + +/** + * @brief + * + * + */ +class FormInputPassword extends FormInput{ + function FormInputPassword($name,$value,$label="",$id="") { + parent::FormInput($name,$value,$label,$id); + $this->type="password"; + } +} + +/** + * @brief + * + */ +class FormInputTextArea extends FormInput{ + var $rows = 5; + var $columns = 20; + function FormInputTextArea($name,$v="",$l="",$i="") { + parent::FormInput($name,$v,$l,$i); + } + function setSize($rows,$c = 0) { + $this->rows = $rows; + $this->columns = $c; + } + + function show() { + $this->showLabel(); + echo ""; + } +} + + +/** + * + * + */ +class FormInputCheckbox extends FormInput { + var $checked = 0; + function FormInputCheckbox($n,$v=0,$l="",$i="") { + parent::FormInput($n,$v,$l,$i); + $this->type='checkbox'; + $this->checked=$v; + } + function show() + { + $this->showLabel(); + echo "checked) { + echo "checked"; + } + echo ">\n"; + } +} +/** + * + * + * + */ +class FormInputButton extends FormInput { + function FormInputButton($n,$v,$l,$i) { + parent::FormInput($n,$v,$l,$i); + $this->type='button'; + } +} + +class FormInputSubmit extends FormInput { + function FormInputSubmit($n,$v="",$l="",$i="") { + parent::FormInput($n,$v,$l,$i); + $this->type='submit'; + } +} + +class FormInputFile extends FormInput { + function __construct($n,$v="",$l="",$i="") { + parent::FormInput($n,$v,$l,$i); + $this->type='file'; + } +} +/** + * \brief This class defines an option for the select input. + * \author EBERSOLD Andre + * \date 29/08/08 + */ +class FormSelectOption { + var $selected,$value,$label; + /** + * + */ + function __construct($label,$value,$selected=false) { + $this->label=$label;$this->value=$value;$this->selected=$selected; + } + /** + * \brief default show function + * + */ + function show() { + echo ""; + } +} + +/** + * @brief The Select field + */ +class FormSelect { + var $options,$selection,$size; + var $tabindex,$disabled,$name; + /** + * Default constructor + * an option is 'selected' and has a 'value' + */ + function __construct($name,$options=Array()) { + $this->tabindex = 0; + $this->selection = false; + $this->size = 10; + $this->name = $name; + $this->options = $options; + } + + /** + * @brief Show function that echo's the selection field + * + */ + function show() { + echo ""; + } +} + +/** + * @brief a formulare + * + */ +class Form { + var $method ="POST"; + var $action = ""; + var $inputs = Array(); + var $count = 0; + var $class = ""; + var $id =""; + var $encode = "multipart/form-data"; + var $onSubmit =""; + + function Form($action = "",$method = "POST") { + if ($action != "") { + $this->action=$action; + } + $this->method = $method; + } + + function setClass($class= "") { $this->class = $class;} + + function addInput($input) { + $this->inputs[$this->count++] = $input; + } + + function show() { + if ( $this->id == "") { + echo "
\n"; + } else { + echo "\n"; + } + + echo "
"; + echo " "; + foreach ($this->inputs as $input) { + $input->show(); + } + echo " "; + echo "
"; + echo "
\n"; + } +} +/* + vim:syntax on:et:list:sw=4:ts=4 + */ +?> diff --git a/class.fpdfdb.php b/class.fpdfdb.php new file mode 100644 index 0000000..0e0a3c0 --- /dev/null +++ b/class.fpdfdb.php @@ -0,0 +1,165 @@ +conn = mysql_connect($host,$user,$password,false,65536); + //if (! $this->conn) { + // echo "Could not connect to $host as $user\n"; + //} + $this->_dbname = $dbname; + $this->_host = $host; + $this->_password = $password; + $this->_user = $user; + + //mysql_select_db($dbname,$this->conn); + //mysql_query("SET NAMES 'utf8'"); + /* Record version ... select VERSION();*/ + if (version_compare(PHP_VERSION,'5.4.0','>')) { + ini_set('magic_quotes_runtime',0); + } + parent::FPDF(); + + $this->mysqli = new mysqli($host,$user,$password,$dbname); + $this->mysqli->set_charset('utf-8'); + } + + function __destruct () { + if ($this->conn != null) { + $this->cleanDb(); + } + //if (defined($this->mysqli)) { + $this->mysqli->close(); + //} + } + + /** + * + * + * + */ + function doQuery($sql,$count = "") { + $ident = Array('total_matches' => 0 , 'records' => array ()); + //$result = mysql_query($sql,$this->conn); + $result = $this->mysqli->query($sql); + if ($result ) { + $i = 0; + //while ($ident["records"][$i++] = mysql_fetch_array($result,MYSQL_ASSOC)) ; + //mysql_free_result($result); + while ($ident["records"][$i++] = $result->fetch_array(MYSQLI_ASSOC)) ; + $result->close() ; + $ident['total_matches'] = $i; + // Stating version 5 of mysql the queries can be more + // sofiticated + if ($count != "" ) { + //$result = mysql_query($count,$this->conn); + //$row= mysql_fetch_row($result); + $result = $this->mysqli->query($count); + $row = $result->fetch_array(); + $ident["total_matches"] = (int)$row[0]; + //mysql_free_result($result); + $result->close(); + } + } else { + error_log("doQuery ".$sql." Failed:".mysql_error(),0); + $ident['result']="Failed"; + } + return $ident; + } + + function doQueryImpr($sql,$count = "") { + $ident = Array('total_matches' => 0 , 'records' => array ()); + $qr = $this->mysqli->multi_query($sql); + $i = 0; + if ($qr ) { + do { + if ($result = $this->mysqli->store_result()) { + while ($row = $result->fetch_row()) { + $ident["records"][$i++] = $row; + } + $result->free(); + } + + $ident['total_matches'] = $i; + // Stating version 5 of mysql the queries can be more + // sofiticated + } while($this->mysqli->next_result()); + } else { + error_log("doQuery ".$sql." Failed:".$this->mysqli->error,0); + $ident['result']="Failed"; + } + return $ident; + } + + function cleanDb() { + mysql_close($this->conn); + unset($this->conn); + } + + function RoundedRect($x, $y, $w, $h, $r, $corners = '1234', $style = '') + { + $k = $this->k; + $hp = $this->h; + if($style=='F') + $op='f'; + elseif($style=='FD' || $style=='DF') + $op='B'; + else + $op='S'; + $MyArc = 4/3 * (sqrt(2) - 1); + $this->_out(sprintf('%.2F %.2F m',($x+$r)*$k,($hp-$y)*$k )); + + $xc = $x+$w-$r; + $yc = $y+$r; + $this->_out(sprintf('%.2F %.2F l', $xc*$k,($hp-$y)*$k )); + if (strpos($corners, '2')===false) + $this->_out(sprintf('%.2F %.2F l', ($x+$w)*$k,($hp-$y)*$k )); + else + $this->_Arc($xc + $r*$MyArc, $yc - $r, $xc + $r, $yc - $r*$MyArc, $xc + $r, $yc); + + $xc = $x+$w-$r; + $yc = $y+$h-$r; + $this->_out(sprintf('%.2F %.2F l',($x+$w)*$k,($hp-$yc)*$k)); + if (strpos($corners, '3')===false) + $this->_out(sprintf('%.2F %.2F l',($x+$w)*$k,($hp-($y+$h))*$k)); + else + $this->_Arc($xc + $r, $yc + $r*$MyArc, $xc + $r*$MyArc, $yc + $r, $xc, $yc + $r); + + $xc = $x+$r; + $yc = $y+$h-$r; + $this->_out(sprintf('%.2F %.2F l',$xc*$k,($hp-($y+$h))*$k)); + if (strpos($corners, '4')===false) + $this->_out(sprintf('%.2F %.2F l',($x)*$k,($hp-($y+$h))*$k)); + else + $this->_Arc($xc - $r*$MyArc, $yc + $r, $xc - $r, $yc + $r*$MyArc, $xc - $r, $yc); + + $xc = $x+$r ; + $yc = $y+$r; + $this->_out(sprintf('%.2F %.2F l',($x)*$k,($hp-$yc)*$k )); + if (strpos($corners, '1')===false) + { + $this->_out(sprintf('%.2F %.2F l',($x)*$k,($hp-$y)*$k )); + $this->_out(sprintf('%.2F %.2F l',($x+$r)*$k,($hp-$y)*$k )); + } + else + $this->_Arc($xc - $r, $yc - $r*$MyArc, $xc - $r*$MyArc, $yc - $r, $xc, $yc - $r); + $this->_out($op); + } + + function _Arc($x1, $y1, $x2, $y2, $x3, $y3) + { + $h = $this->h; + $this->_out(sprintf('%.2F %.2F %.2F %.2F %.2F %.2F c ', $x1*$this->k, ($h-$y1)*$this->k, + $x2*$this->k, ($h-$y2)*$this->k, $x3*$this->k, ($h-$y3)*$this->k)); + } + +} + +?> diff --git a/class.http.Request.php b/class.http.Request.php new file mode 100644 index 0000000..4d993db --- /dev/null +++ b/class.http.Request.php @@ -0,0 +1,169 @@ +allowedKeys as $k) + { + $this->data = isset($vars[$k])?\array_merge($this->data,$vars[$k]):$this->data; + } + } + + /** + * implement ArrayAccess method + * + */ + public function offsetSet($offset,$value) + { + if (is_null($offset)) + { + $this->data[] = $value; + } else + { + $this->data[$offset] = $value; + } + } + + /** + * implement ArrayAccess method + * + */ + public function offsetExists($offet) + { + return isset($this->data[$offset]); + } + + /** + * implement ArrayAccess method + * + */ + public function offsetUnset($offset) + { + unset($this->data[$offset]); + } + + /** + * implement ArrayAccess method + * + */ + public function offsetGet($offset) + { + return isset($this->data[$offset]) ? $this->data[$offset] : null; + } + + + /** + * implement IRequest method + * + */ + public function getHeader($name) + { + } + + /** + * Lets you access post and get parameters by the index + * In case of json requests the encoded json body is accessed + * + * @param string $key the key which you want to access in the URL Parameter + * placeholder, $_POST or $_GET array. + * The priority how they're returned is the following: + * 1. URL parameters + * 2. POST parameters + * 3. GET parameters + * @param mixed $default If the key is not found, this value will be returned + * @return mixed the content of the array + * @since 6.0.0 + */ + public function getParam($key, $default = null) + { + if ( isset($_GET[$key]) ) + { + return $_GET[$key] ; + } + elseif ( isset($_POST[$key]) ) + { + return $_POST[$key] ; + } + else + { + return $default; + } + + } + + /** + * + * @return string the server host + */ + public function getServerHost() + { + $host = "localhost"; + if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) + { + } else + { + if (isset($_SERVER['HTTP_HOST'])) + { + $host = $_SERVER['HTTP_HOST']; + } elseif (isset($_SERVER['SERVER_NAME'])) { + $host = $_SERVER['SERVER_NAME']; + } + } + return $host; + + } + /** + * @brief return Client IP address even if server is behind a proxy + */ + function remoteAddr() { + if (isset($_SERVER['HTTP_X_FORWARDED_FOR'] )) + { + return $_SERVER['HTTP_X_FORWARDED_FOR']; + } else if (isset($_SERVER['REMOTE_ADDR'] )) { + return $_SERVER['REMOTE_ADDR']; + } else + { + return "0"; + } + } + /** + * + */ + public function getScheme() + { + $protocol = "http://"; + if (isset($_SERVER['HTTPS']) && + ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1) || + isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && + $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') { + $protocol = 'https://'; + } + return $protocol; + } + + public function getMethod() + { + return $_SERVER['REQUEST_METHOD']; + } + + public function getPathInfo() + { + return $_SERVER['PATH_INFO']; + } +} + +?> diff --git a/class.images.php b/class.images.php new file mode 100644 index 0000000..de118aa --- /dev/null +++ b/class.images.php @@ -0,0 +1,124 @@ +src_folder = $src_dir; + $this->dst_folder = $dst_dir; + $this->width = $width; + $this->height = $height; + } + /** + * + */ + function do_batch() + { + $pics = $this->directory($this->src_folder,"jpg,JPG,JPEG,jpeg,mng,PNG"); + $pics = $this->ditchtn($pics,"tn_"); /* remove thumbs from list */ + + foreach ($pics as $p) + { + $this->createthumb($p,$dst_folder."/tn_".$p,$this->width,$this->height); + } + } + + /** + * + */ + function ditchtn($arr,$thumbname) + { + foreach ($arr as $item) + { + if (!preg_match("/^".$thumbname."/",$item)){$tmparr[]=$item;} + } + return $tmparr; + } + + /* + Function createthumb($name,$filename,$new_w,$new_h) + creates a resized image + variables: + $name Original filename + $filename Filename of the resized image + $new_w width of resized image + $new_h height of resized image + */ + function createthumb($name,$filename,$new_w,$new_h) + { + $system=explode(".",$name); + if (preg_match("/jpg|jpeg/",$system[1])){$src_img=imagecreatefromjpeg($name);} + if (preg_match("/png/",$system[1])){$src_img=imagecreatefrompng($name);} + $old_x=imageSX($src_img); + $old_y=imageSY($src_img); + if ($old_x > $old_y) + { + $thumb_w=$new_w; + $thumb_h=$old_y*($new_h/$old_x); + } + if ($old_x < $old_y) + { + $thumb_w=$old_x*($new_w/$old_y); + $thumb_h=$new_h; + } + if ($old_x == $old_y) + { + $thumb_w=$new_w; + $thumb_h=$new_h; + } + $dst_img=ImageCreateTrueColor($thumb_w,$thumb_h); + imagecopyresampled($dst_img,$src_img,0,0,0,0,$thumb_w,$thumb_h,$old_x,$old_y); + if (preg_match("/png/",$system[1])) + { + imagepng($dst_img,$filename); + } else { + imagejpeg($dst_img,$filename); + } + imagedestroy($dst_img); + imagedestroy($src_img); + } + + /* + Function directory($directory,$filters) + reads the content of $directory, takes the files that apply to $filter + and returns an array of the filenames. + You can specify which files to read, for example + $files = directory(".","jpg,gif"); + gets all jpg and gif files in this directory. + $files = directory(".","all"); + gets all files. + */ + function directory($dir,$filters) + { + $handle=opendir($dir); + $files=array(); + if ($filters == "all"){while(($file = readdir($handle))!==false){$files[] = $file;}} + if ($filters != "all") + { + $filters=explode(",",$filters); + while (($file = readdir($handle))!==false) + { + for ($f=0;$f diff --git a/class.json-rpc.php b/class.json-rpc.php new file mode 100644 index 0000000..7a889ea --- /dev/null +++ b/class.json-rpc.php @@ -0,0 +1,147 @@ +url = $url; + $this->proxy= $proxy; + $this->id = 1; + } + + /** + * + */ + public function __call($method,$params) { + // pre cond + if ( !is_scalar($method)) { + throw new Exception('Method name issue'); + } + if ( !is_array($params)) { + throw new Exception('Params issue should ne an array'); + } + // request + $request = array('method' => $method, + 'params' => $params, + 'id' => $this->id); + $request = json_encode($request); + // do http request + $opts = array('http' => array( + 'method' => 'POST', + 'header' => 'Content-type: application/json', + 'content' => $request + )); + + $context = stream_context_create($opts); + if ($data = file_get_contents($this->url,false,$context)) { + $response = json_decode($data,true); + } + + if (!is_null($response['error'])) { + throw new Exception('Request error:'.$response['error']); + } + return $response['result']; + } +}; + +/** + * Starting from a object encode and decode json-rpc + * + */ +class JsonRPCServer { + + public function __construct() { + } + /** + * + */ + public static function is_json_rpc() { + if ( $_SERVER['REQUEST_METHOD'] != 'POST' || + empty($_SERVER['CONTENT_TYPE']) || + $_SERVER['CONTENT_TYPE'] != 'application/json; charset=UTF-8') { + return false; + } else return true; + } + function getContent() { + $request = json_decode(file_get_contents('php://input'),true); + return $request; + } + + static function handle($object,$request) { + if (!JsonRPCServer::is_json_rpc()) { + return false; + } + // reads the input data + //$request = json_decode(file_get_contents('php://input'),true); + + // executes the task on local object + try { + if ($result = @call_user_func_array(array($object,$request['method']),$request['params'])) { + $response = array ( + 'id' => $request['id'], + 'result' => $result, + 'error' => NULL + ); + } else { + $response = array ( + 'id' => $request['id'], + 'result' => 0, + 'error' => NULL + ); + if (is_array($result)) { + error_log("json-rpc: unknow method ".$request['method']." or incorrect parameters (...) res=".$result[0]); + } else + error_log("json-rpc: unknow method ".$request['method']." or incorrect parameters (...) res=".$result); + } + } catch (Exception $e) { + $response = array ( + 'id' => $request['id'], + 'result' => NULL, + 'error' => $e->getMessage() + ); + } + if (!empty($request['id'])) { + //$ur = iconv('UTF-8','UTF-8//IGNORE',$response); + //header('content-type: application/json; charset=utf-8'); + header('content-type: application/json; charset=iso-8859-1'); + header('X-JSON: '.json_encode($response)); + $json = json_encode($response); + switch (json_last_error()) + { + case JSON_ERROR_NONE: + echo $json; + break; + case JSON_ERROR_DEPTH: + error_log("json-rpc json-encode error: Depth"); + break; + case JSON_ERROR_STATE_MISMATCH: + error_log("json-rpc json-encode error: state mismatch"); + break; + case JSON_ERROR_CTRL_CHAR: + error_log("json-rpc json-encode error: control char"); + break; + case JSON_ERROR_SYNTAX: + error_log("json-rpc json-encode error: syntax"); + break; + case JSON_ERROR_UTF8: + error_log("json-rpc json-encode error: utf8"); + break; + default: + error_log("json-rpc json-encode error: inconnue"); + break; + + } + } + return true; + } +}; +?> diff --git a/class.logging.php b/class.logging.php new file mode 100644 index 0000000..5fe5f38 --- /dev/null +++ b/class.logging.php @@ -0,0 +1,68 @@ +lopen(); + } + } + function __destruct() { + if ( is_resource($this->fp) { + $this->lclose(); + } + } + + + public function logError($message) { + // Log an error somewhere else then apache log file + if ( ! is_resource($this->fp) { + $this->lopen(); + } + $script_name = pathinfo($_SERVER['PHP_SELF'],PATHINFO_FILENAME); + $time = @date('[d/M/Y:H:i:s]'); + fwrite($this->fp,"".$time." (".$script_name.") ".$message.PHP_EOL); + } + public function logInfo($message) { + // Log information + if ( ! is_resource($this->fp) { + $this->lopen(); + } + $script_name = pathinfo($_SERVER['PHP_SELF'],PATHINFO_FILENAME); + $time = @date('[d/M/Y:H:i:s]'); + fwrite($this->fp,"".$time." (".$script_name.") ".$message.PHP_EOL); + } + + public function logTransaction($message) { + // Log financial transaction + if ( ! is_resource($this->fp) { + $this->lopen(); + } + + $script_name = pathinfo($_SERVER['PHP_SELF'],PATHINFO_FILENAME); + $time = @date('[d/M/Y:H:i:s]'); + fwrite($this->fp,"".$time." (".$script_name.") ".$message.PHP_EOL); + } + + private function lopen() { + if (strtoupper(substr(PHP_OS,0,3)) === 'WIN') { + } else { + $log_file_default = '/tmp/aebwww.log'; + } + $lfile = $this->log_file ? $this->log_file : $log_file_default; + + $this->fp = fopen($lfile,'a') or error_log("Logging can't open file : ".$log_file); + + } + + public function lclose() { + fclose($this->fp); + } + +} +?> diff --git a/class.menu.php b/class.menu.php new file mode 100644 index 0000000..7b198fd --- /dev/null +++ b/class.menu.php @@ -0,0 +1,169 @@ +name = $name; + $this->link = $link; + if ( $sub != null ) { + $this->sub = $sub; + } + } + function isSubMenu() {return isset($this->sub);} + + function showHorizontal($parent,$pos,$level=0) { + $res = "
  • "; + if ($this->isSubMenu()) { + $res .= "".$this->name.""; + $res .= $this->sub->showSubMenu($parent,$pos); + } else { + $res .="link."'>".$this->name."
  • \n"; + } + return $res; + } + /** + * + * + */ + function show($parent,$pos,$level=0) { + $result = ""; + if ($this->isSubMenu()) { + $result.="
  • "; + $result.="link."\">".$this->name."\n
  • \n"; + + } else { + $result.="
  • "; + $result.="link."\">".$this->name."
  • \n"; + } + return $result; + } +} + +/** + * @brief Class used to build Menus + * + * + */ +class Menu { + var $parent = ""; + var $parent_item = 0; + var $title; + var $id; + var $items; + var $type='vertical'; + + /** + * + */ + function Menu($id="Menu",$title="home",$type='vertical') + { + $this->title = $title; + $this->id = $id; + $this->type = $type; + $this->items = array(); + } + + function addMenuItem($name,$link) { + $this->items[$name] = new MenuItem($name,$link); + } + function addSubMenu($name,$link,$sub) { + $this->items[$name] = new MenuItem($name,$link,$sub); + } + + /** + * @brief Show Vertical Menu + * + * + */ + function showVertical($parent="") + { + if ($parent == "") { + // Display Menu title + $result="id; + $result.="\">id."\">"; + $result.=$this->title.""; + $result.="
      id."\" onmouseout=\"hideMenu(event,'".$this->id."',0)\" onmouseover=\"stopHideMenu(0)\">\n"; + echo "$result"; + $i = 1; + $result=""; + foreach ($this->items as $item) { + $result.=$item->show($this->id,$i); + $i+= 1; + } + + $result.="
    \n"; + } + echo $result; + } + + /** + * @brief Show Horizontal Menu + * + */ + function showHorizontal($parent="") { + $result="
      \n"; + $res = ""; + $i = 1; + foreach ($this->items as $item) { + $res.=$item->showHorizontal($this->id,$i); + $i+= 1; + } + $icon = "
    • "; + $result.=$res."".$icon."
    \n"; + echo $result; + } + /** + * @brief + * + */ + function showSubMenu($parent,$pos) { + $i = 1; + $result = ""; + if ($this->type == "horizontal" ){ + $result.="
      \n"; + } + foreach ($this->items as $item) { + if ($this->type =='vertical' ) { + $result.=$item->show($parent."_".$pos,$i,1); + } else { + $result.=$item->showHorizontal($parent.$pos."_",$i,1); + } + $i+= 1; + } + if ($this->type == "horizontal" ){ + $result.="
    \n"; + } + return $result; + } + + /** + * @brief main entry to show a menu + * + */ + function show($parent = "") { + if ($this->type == 'vertical') { + $this->showVertical($parent); + } else { + $this->showHorizontal($parent); + } + + } +} +?> diff --git a/class.nntp.php b/class.nntp.php new file mode 100644 index 0000000..834c904 --- /dev/null +++ b/class.nntp.php @@ -0,0 +1,9 @@ + diff --git a/class.notebook.php b/class.notebook.php new file mode 100644 index 0000000..5cf1eb8 --- /dev/null +++ b/class.notebook.php @@ -0,0 +1,73 @@ +title;} + + function show_title($obj) { + echo "
  • "; + echo "title."');\" id=\"center\">"; + echo $this->title."
  • "; + } + /** + * \brief this function might be reimplemented for + * each new page + */ + function content() { + } + /** + * \brief This page display the decoration + */ + function show() { + echo "
    "; + $this->content(); + echo "
    "; + } +} + +/** + * \brief This class will be used to create and + * display a note book + * \author EBERSOLD ANDRE + * \date 01/09/08 + * + */ +class Notebook { + var $pages=Array(); + var $title; + var $obj="NoteWin"; + + function __construct() { + } + + fucntion addPage($page) { + $pages[] = $page; + } + + function show() { + echo "
      "; + echo "
    "; + foreach ($pages as $page) { + $page->show_title($this->obj); + } + foreach ($pages as $page) { + $page->show($this->obj); + } + echo "
    "; + } +} +/* + vim:et:sw=4:ts=4:enc=utf-8 + */ +?> diff --git a/class.ofx.php b/class.ofx.php new file mode 100644 index 0000000..f9a523d --- /dev/null +++ b/class.ofx.php @@ -0,0 +1,108 @@ +texte, '<'.$code.'>') ; + if (! ($debut === false) ) { + $fin = strpos($this->texte, '')+strlen($code)+3 ; + $this->para = substr($this->texte, $debut, $fin-$debut) ; + $this->texte = substr($this->texte, $fin) ; + } else + { + error_log("no more paragraph ".$code." début=".$debut." text:".substr($this->texte,0,20)); + $this->para = '' ; + } + } + + private function valeur($parametre) { + //global $paragraphe ; + $debut = strpos($this->para, '<'.$parametre.'>') ; + if ($debut>0) { + $debut = $debut+strlen($parametre)+2 ; + $fin = strpos($this->para, '<',$debut+1) ; + return trim(substr($this->para, $debut, $fin-$debut)) ; + } else return '' ; + } + + public function onAccount($codeBanque,$codeGuichet,$codeCompte) + { + //mysql_select_db($database_locations, $locations); + //$query_rs_compte = "SELECT id, libelle FROM tbl_compte WHERE code_banque='$code_banque' AND code_guichet='$code_guichet' AND no_compte='$no_compte'"; + //$rs_compte = mysql_query($query_rs_compte, $locations) or die(mysql_error()); + //$row_rs_compte = mysql_fetch_assoc($rs_compte); + //$compte_id = $row_rs_compte['id'] ; + } + + public function onMouvement($type,$date,$montant,$reste,$libelle,$info) + { + } + +public function parse($fichier) +{ + $ofx_msg = ""; + //if($_size_ > 3200000) $ofx_msg = "Erreur: le fichier est trop lourd (max 3M)"; + if(empty($errStr)) + { + if (file_exists($fichier)) { + $file = fopen($fichier, "r") ; + $this->texte = ''; + while (!feof($file)) $this->texte .= fread($file, 8192); + fclose($file); + $this->paragraphe('BANKACCTFROM') ; + if (strlen($this->para) > 0) { + $code_banque = $this->valeur('BANKID') ; + $code_guichet = $this->valeur('BRANCHID') ; + $no_compte = $this->valeur('ACCTID') ; + $this->onAccount($code_banque,$code_guichet,$no_compte); + $compte_id = 512000; + //$totalRows_rs_compte = mysql_num_rows($rs_compte); + $totalRows_rs_compte = 1; + if ($totalRows_rs_compte == 1) { + $values = '' ; + $a_supprimer = array("'", ".") ; + $this->paragraphe('STMTTRN') ; + $i = 0 ; + while (strlen($this->para)>0) { + $i += 1 ; + $type = $this->valeur('TRNTYPE') ; + $date = $this->valeur('DTPOSTED') ; + $montant = $this->valeur ('TRNAMT') ; + $reste = $montant ; + $banque_mouvement_id = $compte_id.' - '.$this->valeur('FITID') ; + $libelle = ucwords(strtolower(str_replace($a_supprimer, ' ', $this->valeur('NAME')))) ; + $info = ucwords(strtolower(str_replace($a_supprimer, ' ', $this->valeur ('MEMO')))) ; + //$values .= "(".$compte_id.",'".$type."',".$date.",".$montant.",".$reste. + // ",'".$banque_mouvement_id."','".$libelle."','".$info."'), " ; + $this->paragraphe('STMTTRN') ; + $this->onMouvement($type,$date,$montant,$reste,$libelle,$info); + } + //$values = substr($values, 0, strlen($values)-2) ; + //mysql_select_db($database_locations, $locations); + //$query_insert = "INSERT IGNORE INTO tbl_mouvement (compte_id, type, `date`, montant, reste, banque_mouvement_id, libelle, info) VALUES $values"; + //if (mysql_query($query_insert, $locations) == 1) + // $ofx_msg = "Importation réussie de $i mouvements dans le compte ".$row_rs_compte['libelle'].'
    '.mysql_info($locations) ; + //else $ofx_msg = "Erreur dans l'insertion des mouvements" ; + + } else $ofx_msg = "Erreur: le compte bancaire $code_banque / $code_guichet / $no_compte n'existe pas" ; + } else $ofx_msg = "Erreur: le fichier ne semble pas être un fichier OFX valide" ; + } else $ofx_msg = "Erreur: échec lors de l'ouverture du fichier $fichier" ; + } else $ofx_msg = "Erreur: le fichier n'a pas été téléchargé" ; + error_log("Parsing end ".$i." : ".$ofx_msg); + } +} + +?> diff --git a/class.page.php b/class.page.php new file mode 100644 index 0000000..e7053e4 --- /dev/null +++ b/class.page.php @@ -0,0 +1,246 @@ +title = $t; + } + function title() + { + return $this->title; + } + function redirectLocal($url) { + $_scheme = $this->request->getScheme(); + if (empty($this->alias)) { + header("Location: ".$_scheme."".$this->request->getServerHost()."/".$url); + } else + header("Location: ".$_scheme."".$this->request->getServerHost()."/".$this->alias."/".$url); + die(); + } + /** + * @brief This function computes the scheme of the current request. + pretty usefull to complete the link area and so on. + */ + function siteScheme() + { + $protocol = "http://"; + if (isset($_SERVER['HTTPS']) && + ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1) || + isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && + $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') { + $protocol = 'https://'; + } + return $protocol; + } + /** + * @brief return Client IP address even if server is behind a proxy + */ + function remoteAddr() { + $addr = "0"; + $host = ""; + if (isset($_SERVER['HTTP_X_FORWARDED_FOR'] )) + { + $host = $_SERVER['HTTP_X_FORWARDED_FOR']; + } else if (isset($_SERVER['REMOTE_ADDR'] )) { + $host = $_SERVER['REMOTE_ADDR']; + } + $addr = gethostbyname($host); + //error_log("remoteAddr:".$host." <".$addr.">"); + return $addr; + + } + ################################################################################################# + ## INCLUSION JAVASCRIPT GENERIQUE + ################################################################################################# + function generate_top() { + header("Content-Type: text/html; charset=".$this->charset.""); + echo "\n"; + echo ""; + echo "\n"; + echo " charset."\">\n"; + echo " ".$this->title."\n"; + //echo " \n"; + echo " \n"; + /* May be can be disabled in production */ + echo " \n"; + echo " \n"; + echo " \n"; + echo " keywords."\">\n"; + echo " description()."\">\n"; + echo " \n"; + } + + function generate_links() { + + #echo "\n"; + echo "\n"; + echo << + + + +FIN; + + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + # + # Was necessary for IE !!! + # + echo "\n"; + } + + + + # + # xgui links + # + function generate_xgui() { + echo ""; + echo "\n"; + echo "\n"; + + } + + function top () { + } + function bottom () { + } + function news() { + "
    "; + } + + function hMenu () { + echo "
    \n"; + #echo ""; + } + + function vMenu () { + if (!defined($this->vmenu)) { + $this->vmenu = new Menu("Menu1"); + $this->vmenu->addMenuItem("accueil","/app/index.php"); + $this->vmenu->addMenuItem("register","/app/registration/register.php"); + } + $this->vmenu->show(); + } + + + function main() { + echo "

    Main entry

    "; + } + function _login() { + } + + function showTitle($title) { + echo "

    $title

    \n"; + } + function _content() { + echo "\n
    \n
    \n"; + $this->main(); + echo "
    \n"; /* end content */ + } + function show () { + $this->_HtmlHeader(); + echo "
    \n"; + echo "
    "; + if ($this->_layout_class != "") + echo "
    \n"; /* end layout */ + if ($this->_withHeader) + { + echo "\n"; + } + if ($this->_withMenuH) + { + echo "\n"; + } + echo "\n"; + if ($this->_withMenuV ) + { + echo "\n"; + } + echo "
    "; + $this->news(); + $this->_content(); + echo "
    \n"; /* end main */ + echo "
    "; + $this->bottom(); + echo "
    \n"; /* end bottom */ + if ($this->_layout_class != "") + echo "
    \n"; /* end layout */ + echo "
    \n"; /* end row */ + echo "
    \n"; /* end container */ + $this->_login(); + echo "\n\n"; + return true; + } +} +?> diff --git a/class.router.php b/class.router.php new file mode 100644 index 0000000..cd7a54f --- /dev/null +++ b/class.router.php @@ -0,0 +1,154 @@ + + * @version 1.0 + * @package phplib + */ + +require_once(dirname(__FILE__)."/iface.Request.php"); +require_once(dirname(__FILE__)."/iface.ActionResult.php"); +require_once(dirname(__FILE__)."/class.ActionResults.php"); + +class Route +{ + private $path; + private $callable; + private $matches = []; + private $params = []; + + private $root ="."; + + public function __construct($path,$callable) + { + $this->path = trim($path,'/'); // Remove unecessairy / + $this->callable = $callable; + } + + public function setRoot($_r) + { + $this->root = $_r; + return $this; + } + + public function with($param,$regex) + { + $this->params[$param] = str_replace('(','(?:',regex); + return $this; + } + + public function match($url) + { + $url = trim($url,'/'); + //$path = preg_replace('#:([\w]+)#',[$this,'paramMatch'],$this->path); + $path = preg_replace_callback('#:([\w]+)#',[$this,'paramMatch'],$this->path); + $regex = "#^$path$#i"; + if (!preg_match($regex,$url,$matches)) + { + return false; + } + array_shift($matches); + $this->matches = $matches; + return true; + } + + public function call() + { + if (is_string($this->callable) ) + { + $params = explode('#',$this->callable); + $file = "".$params[0].".php"; + $controler = "compta\\controlers\\" . $params[0]; + + if ( file_exists($this->root.$file) ) + { + require_once($this->root.$file); + $_c = new $controler (); + return call_user_func_array([$_c,$params[1]],$this->matches); + } + return new \HtmlResult("

    router failed

    "); + } + return call_user_func_array($this->callable,$this->matches); + } + + private function paramMatch($match) + { + if (isset($this->params[$match[1]])) + { + return '('. $this->params[$match[1]] . ')'; + } + return '([^/]+)'; + } +} + +/** + * + * + */ +class Router +{ + private $routes = []; + private $namesRoutes = []; + private $request = null; + + public function __construct(IRequest $_r) + { + $this->request = $_r; + } + + public function get($path,$callable,$name = null) + { + return $this->add($path,$callable,$name,'GET'); + } + + public function post($path,$callable,$name = null) + { + return $this->add($path,$callable,$name,'POST'); + } + + public function add($path,$callable,$name,$method) + { + $route = new Route($path,$callable); + $this->routes[$method][] = $route; + if ( is_string($callable) && $name === null) + { + $name = $callable; + } + if ($name) + { + $this->namedRoutes[$name] = $route; + } + return $route; // On retourne la route pour "enchainer" les méthodes + } + + public function run() + { + if (! isset($this->routes[$this->request->getMethod()]) ) + { + // Error should do something + } + foreach($this->routes[$this->request->getMethod()] as $route) + { + if ($route->match($this->request->getPathInfo())) + { + return $route->call(); + } + } + echo "No route"; + // Again no route found + } +} + +/** + * Examples + require_once(dirname(__FILE__)."/class.http.Request.php"); + $req = new Request(); + $r = new Router($req); + $r->get('/',function($id) {echo "Main page"}); + $r->get('/posts/:id',function($id) { echo "$Got id $id" ;} ); + $r->run(); + */ + +?> diff --git a/class.session.php b/class.session.php new file mode 100644 index 0000000..319ad19 --- /dev/null +++ b/class.session.php @@ -0,0 +1,182 @@ +opaqueDb = $_opaqueDb; + } + $this->timeout = 1800; + $this->user_id = (array_key_exists('user_id',$_SESSION))?$_SESSION['user_id']:""; + $this->user_name = (isset($_SESSION['user_name']))?$_SESSION['user_name']:"" ; + $this->user_prenom= (isset($_SESSION['user_prenom']))?$_SESSION['user_prenom']:"" ; + $this->user_email = (isset($_SESSION['user_email']))?$_SESSION['user_email']:"" ; + $this->user_token = (isset($_SESSION['token']))?$_SESSION['token']:"" ; + $this->user_groupe= (isset($_SESSION['user_groupe']))?$_SESSION['user_groupe']:"" ; + $this->updateTimeout(); + } + /** + * @brief Generate a random string to handle session tokens + */ + function generateRandomString($length = 40) { + $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + $charactersLength = strlen($characters); + $randomString = ''; + for ($i = 0; $i < $length; $i++) { + $randomString .= $characters[rand(0, $charactersLength - 1)]; + } + return $randomString; + } + + function updateTimeout() { + $timeout = time(); + if (isset($_SESSION['LAST_ACTIVITY']) && $timeout - $_SESSION['LAST_ACTIVITY'] > $this->timeout) { + session_unset(); // unser $_SESSION variables + session_destroy(); // Destroy session storage + } + $_SESSION['LAST_ACTIVITY'] = time(); + } + /** + * @brief + */ + function createToken() { + $this->user_token = $this->generateRandomString(36); + if ($this->opaqueDb) { + $result = @call_user_func_array(array($this->opaqueDb,"create") + ,array($this->user_token,0)) ; + } + $_SESSION['token'] = $this->user_token; + return $this->user_token; + } + function is_logged_in() { + return ( isset($_SESSION['login'])) && ($_SESSION['login'] != '');} + + function id() { return $this->user_id; } + + function name() {return $this->user_name; } + + function first_name() {return $this->user_prenom; } + + function groupe() {return $this->user_groupe; } + /** + * @note $_SESSION['user_groupe_name'] is set + * in member/class.json_db_user.php + */ + function in_groupe($name) { + return in_array($name,$_SESSION['user_groupe_name']);} + + function last_name() { return $this->user_name;} + + function set_email($email) { $this->user_email = $email; $_SESSION['user_email']=$email;} + + function email() { return $this->user_email;} + + function logout() { + if ($this->opaqueDb) { + $result = @call_user_func_array(array($this->opaqueDb,"destroy") + ,array($this->user_token,0)) ; + } + if (isset($_SESSION['token'])) { unset($_SESSION['token']); } + if (isset($_SESSION['login'] )) { + unset($_SESSION['login']); + unset($login); + } + if (isset($_SESSION['user_groupe']) ) { + unset($_SESSION['user_groupe']); + } + session_destroy(); + } + /* + * @brief Store the requested uri before redirection. + * retrived it back once authenticated + */ + function set_uri($uri) { $_SESSION['req_uri'] = $uri; } + function get_uri() { return $_SESSION['req_uri']; } + function isset_uri() { return isset($_SESSION['req_uri']); } + function unset_uri() { if (isset($_SESSION['req_uri'] )) { unset($_SESSION['req_uri']);} } + /** + * @brief User is authorized. + * if database is available, update and reload + */ + function login($id,$nom,$prenom,$groupe) { + $_SESSION['user_id'] = $id; + $_SESSION['user_name'] = $nom; + $_SESSION['user_prenom'] = $prenom; + $_SESSION['user_groupe'] = $groupe; + if ($this->opaqueDb) { + $result = @call_user_func_array(array($this->opaqueDb,"updateState") + ,array($this->user_token,"Authenticated")) ; + } + } + /** + * @brief Refresh session info based on database state + * time + */ + function refresh() { + + $this->from_token($_SESSION['token']); + } + + /** + * @brief From token, get session formation from token + * user, first_name state and email1 + * + */ + function from_token($token) + { + $_ret = false; + if ($this->opaqueDb) { + $result = @call_user_func_array(array($this->opaqueDb,"getAll") + ,array($token)) ; + if (sizeof($result) > 0 ) { + $_SESSION['state'] = $result[3]; + $_SESSION['token'] = $token; + $this->user_token = $token; + $this->user_email = $result[2]; + $this->user_name = $result[0]; + $this->user_id = $result[5]; + $ret = true; + } + } + + return $_ret; + } + + /** + * @brief return the session state. I'm not sur If I should extract + * it from the global Session or from the Data base + */ + function get_state() + { + return $_SESSION['state']; + } + /** + * + */ + function set_state($token,$state) + { + if ($this->user_token == $token) + { + $_SESSION['state'] = $state; + if ($this->opaqueDb) { + $result = @call_user_func_array(array($this->opaqueDb,"updateState") + ,array($this->user_token,$state)) ; + } + } else { + error_log("Session::set_state Failed token miss matche"); + } + } +} +/** + vim:et:sw=4:ts=4:enc=utf-8 + */ +?> diff --git a/class.sitemap.php b/class.sitemap.php new file mode 100644 index 0000000..57d0569 --- /dev/null +++ b/class.sitemap.php @@ -0,0 +1,59 @@ +url = $u; + + $this->changefreq ="monthly"; + $this->priority =$p; + } + + function createItem() { + $item=""; + $item.="".$this->url.""; + $item.="".$this->lastupdate.""; + $item.="".$this->changefreq.""; + $item.="".$this->priority.""; + $item.=""; + return $item; + } +}; + +class SitemapCreator { + var $contentType = "application/xml"; + var $encoding = "utf-8"; + var $items = array(); + function __construct() + { + header("Content-Type:".$this->contentType."; charset=".$this->encoding."; filename=sitemap.xml"); + } + + function addItem($i) { + $this->items[] = $i; + } + + function createSitemap() { + $sitemap =" "; + foreach ($this->items as $item) { + $sitemap.=$item->createItem(); + } + $sitemap .=""; + return $sitemap; + } + + function output() { + echo $this->createSitemap(); + } + +} + + +/* + :vim:enciding=utf-8:fileencoding=utf-8:et:sw=2:ts-2 + */ +?> diff --git a/class.smtp.php b/class.smtp.php new file mode 100644 index 0000000..2f4f933 --- /dev/null +++ b/class.smtp.php @@ -0,0 +1,671 @@ +serveur = $serveur; + } + if($user){ + $this->Authentification_smtp = true; + $this->login_smtp = $user; + $this->mdp_smtp = $pass; + } + $this->port = $port; + if($NomDuDomaine){ + $this->NomDuDomaine = $NomDuDomaine; + } + $this->debug = $debug; + } + + + //************************************************************************** + // Fonction de connection SMTP + //************************************************************************** + function Connect_SMTP(){ + // Definition du charset + if(!$this->CHARSET){ $this->CHARSET = mb_internal_encoding(); } + + // Connection au serveur SMTP + $this->smtp_connection = fsockopen($this->serveur, // Serveur + $this->port, // Port de connection + $num_erreur, // Numéros de l' erreur + $msg_erreur, // Message d' erreur + $this->time_out); // Durée de la connection en secs + if(!$this->smtp_connection){// Vérification de la connection + $this->erreur = 'Impossible de se connecter au serveur SMTP !!!
    '."\r\n" + .'Numéro de l' erreur: '.$num_erreur.'
    '."\r\n" + .'Message renvoyé: '.$msg_erreur.'
    '."\r\n"; + return false; + } + + // Suppression du message d' accueil + $reponce = $this->get_smtp_data(); + // Debug + if($this->debug){ + echo '
    Connection
    ',"\r\n",str_replace("\r\n", '
    ', $reponce['msg']); + } + + // On règle le timeout du serveur SMTP car parfois, le serveur SMTP peut être un peut lent à répondre + // Windows ne comprend pas la fonction socket_set_timeout donc on vérifi que l' on travail sous Linux + if(substr(PHP_OS, 0, 3) !== 'WIN'){ + socket_set_timeout($this->smtp_connection, $this->time_out, 0); + } + + //********************************************************************** + // Commande EHLO et HELO + if($this->NomDuDomaine === ''){// On vérifit si le nom de domaine à été renseigné + if($_SERVER['SERVER_NAME'] !== ''){ + $this->NomDuDomaine = $_SERVER['SERVER_NAME']; + }else{ + $this->NomDuDomaine = 'localhost.localdomain'; + } + } + + if(!$this->Commande('EHLO '.$this->NomDuDomaine, 250)){// Commande EHLO + // Deusième commande EHLO -> HELO + if(!$this->Commande('HELO '.$this->NomDuDomaine, 250, 'Le serveur refuse l' authentification (EHLO et HELO) !!!')){// Commande HELO + return false; + } + } + + if($this->tls && !$this->Commande('STARTTLS', 220, 'Le serveur refuse la connection sécurisée ( STARTTLS ) !!!')){// Commande STARTTLS + return false; + } + + if($this->Authentification_smtp){// On vérifi si l' on a besoin de s' authentifier + //****************************************************************** + // Authentification + //****************************************************************** + if(!$this->Commande('AUTH LOGIN', 334, 'Le serveur refuse l' authentification (AUTH LOGIN) !!!')){ + return false; + } + + + //****************************************************************** + // Authentification : Login + //****************************************************************** + $tmp = $this->Commande(base64_encode($this->login_smtp), 334, 'Login ( Nom d' utilisateur ) incorrect !!!', 0); + if(!$tmp['no_error']){ + return false; + } + // Debug + if($this->debug){ + echo '
    Envoie du login.
    ',"\r\n",str_replace("\r\n", '
    ', $tmp['msg']); + } + + + //****************************************************************** + // Authentification : Mot de passe + //****************************************************************** + $tmp = $this->Commande(base64_encode($this->mdp_smtp), 235, 'Mot de passe incorrect !!!', 0); + if(!$tmp['no_error']){ + return false; + } + // Debug + if($this->debug){ + echo '
    Envoie du mot de passe.
    ',"\r\n",str_replace("\r\n", '
    ', $tmp['msg']); + } + + } + + //********************************************************************** + // Connecté au serveur SMTP + //********************************************************************** + return true; + } + + + //************************************************************************** + // Fonctons de set + //************************************************************************** + function set_from($name, $email='', $org='Localhost'){ + $this->FromName = $name; + if($this->Encode){ + $this->FromName = $this->encode_mimeheader(mb_convert_encoding($this->FromName, $this->ISO, $this->CHARSET), $this->ISO); + } + if(!empty($email)){ + $this->From = $email; + } + $this->org = $org; + unset($name, $email, $org); + } + + function set_encode($ISO, $CHARSET=''){ + $this->Encode = true; + $this->ISO = $ISO; + $this->CHARSET = $CHARSET; + unset($ISO, $CHARSET); + } + + + //************************************************************************** + // System d' encodage par Pierre CORBEL + //************************************************************************** + function encode_mimeheader($string){ + $encoded = ''; + $CHARSET = mb_internal_encoding(); + // Each line must have length <= 75, including `=?'.$this->CHARSET.'?B?` and `?=` + $length = 75 - strlen('=?'.$this->CHARSET.'?B?') - 2; + $tmp = mb_strlen($string, $this->CHARSET); + // Average multi-byte ratio + $ratio = mb_strlen($string, $this->CHARSET) / strlen($string); + // Base64 has a 4:3 ratio + $magic = floor(3 * $length * $ratio / 4); + $avglength = $magic; + + for($i=0; $i <= $tmp; $i+=$magic) { + $magic = $avglength; + $offset = 0; + // Recalculate magic for each line to be 100% sure + do{ + $magic -= $offset; + $chunk = mb_substr($string, $i, $magic, $this->CHARSET); + $chunk = base64_encode($chunk); + $offset++; + }while(strlen($chunk) > $length); + if($chunk){ + $encoded .= ' '.'=?'.$this->CHARSET.'?B?'.$chunk.'?='."\r\n"; + } + } + // Chomp the first space and the last linefeed + return substr($encoded, 1, -2); + } + + + //************************************************************************** + // Foncton d' ajout de pièce jointe + //************************************************************************** + function add_file($url_file){ + if(!$url_file){ + $this->erreur = 'Champs manquant !!!
    '."\r\n"; + return false; + } + if(!($fp = @fopen($url_file, 'a'))){ + $this->erreur = 'Fichier introuvable !!!
    '."\r\n"; + return false; + } + fclose($fp); + + $file_name = explode('/', $url_file); + $file_name = $file_name[count($file_name)-1]; + $mime = parse_ini_file('./mime.ini'); + $ext = explode('.', $file_name); + $ext = $ext[count($ext)-1]; + + if(IsSet($this->File_joint[$file_name])){ + $file_name = explode('_', str_replace('.'.$ext, '', $file_name)); + if(is_numeric($file_name[count($file_name)-1])){ + $file_name[count($file_name)-1]++; + $file_name = implode('_', $file_name); + }else{ + $file_name = implode('_', $file_name); + $file_name .= '_1'; + } + $file_name .= '.'.$ext; + } + $this->File_joint[$file_name] = array( + 'url' => $url_file, + 'mime' => $mime[$ext] + ); + unset($file_name, $mime, $ext); + } + + + //************************************************************************** + // Entêtes (Headers) + //************************************************************************** + function headers(){ + // Id unique + $Boundary1 = '------------Boundary-00=_'.substr(md5(uniqid(time())), 0, 7).'0000000000000'; + $Boundary2 = '------------Boundary-00=_'.substr(md5(uniqid(time())), 0, 7).'0000000000000'; + $Boundary3 = '------------Boundary-00=_'.substr(md5(uniqid(time())), 0, 7).'0000000000000'; + + $header = ''; + $No_body = 0; + + // Adresse de l'expéditeur (format : Nom ) + if(!empty($this->From)){ + $header .= 'X-Sender: '.$this->From."\n";// Adresse réelle de l'expéditeur + } + // La version mime + if(!empty($this->MIME)){ + $header .= 'MIME-Version: '.$this->MIME."\n"; + } + $header .= sprintf("Message-ID: <%s@%s>%s", md5(uniqid(time())), $this->NomDuDomaine, "\n") + .'Date: '.date('r')."\n" + .'Content-Type: Multipart/Mixed;'."\n" + .' boundary="'.$Boundary1.'"'."\n" + // Logiciel utilisé pour l' envoi des mails + .'X-Mailer: PHP '.phpversion()."\n"; + // Adresse de l'expéditeur (format : Nom ) + if(!empty($this->From)){ + if(!empty($this->FromName)){ + $header .= 'From: "'.$this->FromName.'"'; + }else{ + $header .= 'From: '; + } + $header .= '<'.$this->From.">\n"; + } + $header .= 'X-FID: FLAVOR00-NONE-0000-0000-000000000000'."\n"; + + // Priorité accordée au mail (valeur allant de 1 pour Urgent à 3 pour normal et 6 pour bas) + if(!empty($this->Priority)){ + $header .= 'X-Priority: '.$this->Priority."\n"; + } + // To + if(!empty($this->To)){// A + $header .= 'To: '.$this->To."\n"; + }else{ + $No_body++;// Personne + } + // Cc + if(!empty($this->Cc)){// Copie du mail + $header .= 'Cc: '.$this->Cc."\n"; + }else{ + $No_body++;// Personne + } + // Bcc + if(empty($this->Bcc)){// Blind Carbon Copy, c' est à dire que les adresses qui sont contenue ici seront invisibles pour tout le monde + $No_body++;// Personne + } + // Sujet + if(!empty($this->Sujet)){ + $header .= 'Subject: '.$this->Sujet."\n"; + } + if(!empty($this->Confimation_reception)){// Adresse utilisée pour la réponse au mail + $header .= 'Disposition-Notification-To: <'.$this->Confimation_reception.'>'."\n"; + } + // ReplyTo + if(!empty($this->ReplyTo) && $this->ReplyTo !== $this->From && $this->ReplyTo !== 'root@localhost'){// Adresse utilisée pour la réponse au mail + $header .= 'Reply-to: '.$this->ReplyTo."\n" + .'Return-Path: <'.$this->ReplyTo.">\n"; + } + if(!IsSet($_SERVER['REMOTE_ADDR'])){$_SERVER['REMOTE_ADDR'] = '127.0.0.1';} + if(!IsSet($_SERVER['HTTP_X_FORWARDED_FOR'])){$_SERVER['HTTP_X_FORWARDED_FOR'] = '';} + if(!IsSet($_SERVER['HTTP_USER_AGENT'])){$_SERVER['HTTP_USER_AGENT'] = 'Internet Explorer';} + if(!IsSet($_SERVER['HTTP_ACCEPT_LANGUAGE'])){$_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'Fr-fr';} + $host = 'localhost'; + if(function_exists('gethostbyaddr') && $_SERVER['REMOTE_ADDR'] !== '127.0.0.1'){$host = gethostbyaddr($_SERVER['REMOTE_ADDR']);} + $header .= 'X-Client-IP: '.$_SERVER['REMOTE_ADDR']."\n" + .'X-Client-PROXY: '.$_SERVER['HTTP_X_FORWARDED_FOR']."\n" + .'X-Client-Agent: '.$_SERVER['HTTP_USER_AGENT']."\n" + .'X-Client-Host: '.$host."\n" + .'X-Client-Language: '.$_SERVER['HTTP_ACCEPT_LANGUAGE']."\n" + .'Organization: '.$this->org."\n" + ."\n\n\n" + .'--'.$Boundary1."\n" + .'Content-Type: Multipart/Alternative;'."\n" + .' boundary="'.$Boundary3.'"'."\n" + ."\n\n" + .'--'.$Boundary3."\n"; + if($this->ContentType === 'txt' || $this->ContentType === 'txt/html'){ + $header .= 'Content-Type: Text/Plain;'."\r\n" + .' charset="'.$this->ISO.'"'."\r\n" + .'Content-Transfer-Encoding: '.$this->Encoding."\r\n" + ."\r\n"; + if($this->ContentType === 'txt'){ + $header .= $this->Body."\r\n"; + }else{ + $header .= $this->Body_txt."\r\n"; + } + }elseif($this->ContentType === 'html' || $this->ContentType === 'txt/html'){ + if($this->ContentType === 'txt/html'){ + $header .= '--'.$Boundary3."\r\n"; + } + $header .= 'Content-Type: Text/HTML;'."\r\n" + .' charset="'.$this->ISO.'"'."\r\n" + .'Content-Transfer-Encoding: '.$this->Encoding."\r\n" + ."\r\n" + .''."\r\n" + .''."\r\n" + .''."\r\n" + .''."\r\n" + .''."\r\n" + .$this->Body."\r\n" + .''."\r\n" + .'--'.$Boundary3.'--'."\r\n"; + }else{ + $header .= 'Content-Type: '.$this->ContentType.';'."\r\n" + .' charset="'.$this->ISO.'"'."\r\n" + .'Content-Transfer-Encoding: '.$this->Encoding."\r\n" + ."\r\n" + .$this->Body."\r\n"; + } + $header .= "\n"; + + // On joint le ou les fichiers + if($this->File_joint){ + foreach($this->File_joint as $file_name => $file){ + $header .= '--'.$Boundary1."\n" + .'Content-Type: '.$file['mime'].';'."\n" + .' name="'.$file_name.'"'."\n" + .'Content-Disposition: attachment'."\n" + .'Content-Transfer-Encoding: base64'."\n" + ."\n" + .chunk_split(base64_encode(file_get_contents($file['url'])))."\n" + ."\n\n"; + } + } + $header .= '--'.$Boundary1.'--'; + + if($No_body === 3){ + $this->erreur = 'Le mail n' a pas de destinataire !!!'; + return false; + } + return $header; + } + + + //************************************************************************** + // Envoie du mail avec le serveur SMTP + //************************************************************************** + function smtp_mail($to, $subject, $message, $header=''){ + // Pas de déconnection automatique + $auto_disconnect = false; + // On vérifit si la connection existe + if(empty($this->smtp_connection)){ + if(!$this->Connect_SMTP()){// Connection + $this->erreur .= 'Impossible d' envoyer le mail !!!
    '."\r\n"; + return false; + } + $auto_disconnect = true;// Déconnection automatique activée + } + + // On vérifit Que c' est le premier tour sinon on éfface les anciens paramètres + if($this->Tour){ + if($this->Commande('RSET', 250, 'Envoie du mail impossible !!!')){ + $this->Tour = 0; + } + } + + //********************************************************************** + // Variables temporairement modifiées + if(!empty($to)){ + $this->To = $to; + } + if(!empty($subject)){ + if($this->Encode){ + $this->Sujet = $this->encode_mimeheader(mb_convert_encoding($subject, $this->ISO, $this->CHARSET), $this->ISO); + }else{ + $this->Sujet = mb_encode_mimeheader($subject, $this->ISO); + } + } + + if(is_array($message)){ + $this->Body = $message[0]; + $this->Body_txt = $message[1]; + if($this->Encode){ + $this->Body = mb_convert_encoding($this->Body, $this->ISO, $this->CHARSET); + $this->Body_txt = mb_convert_encoding($this->Body_txt, $this->ISO, $this->CHARSET); + } + }else{ + $this->Body = $message; + if($this->Encode){ + $this->Body = mb_convert_encoding($this->Body, $this->ISO, $this->CHARSET); + } + } + + //********************************************************************** + // Y a t' il un destinataire + if(empty($this->To) && empty($header) && empty($this->Bcc) && empty($this->Cc)){ + $this->erreur = 'Veuillez entrer une adresse de destination !!!
    '."\r\n"; + return false; + } + + //********************************************************************** + // Envoie des informations + //********************************************************************** + + //********************************************************************** + // De Qui + if(!empty($this->From) && !$this->Tour){ + if(!$this->Commande('MAIL FROM:<'.$this->From.'>', 250, 'Envoie du mail impossible car le serveur n' accèpte pas la commande MAIL FROM !!!')){ + return false; + } + $this->Tour = 1; + } + + //********************************************************************** + // A Qui + $A = array(); + if(!empty($this->To)){ + $A[0] = $this->To; + } + if(!empty($this->Bcc)){ + $A[1] = $this->Bcc; + } + if(!empty($this->Cc)){ + $A[2] = $this->Cc; + } + foreach($A as $cle => $tmp_to){ + if(substr_count($tmp_to, ',')){ + $tmp_to = explode(',', $tmp_to); + foreach($tmp_to as $cle => $tmp_A){ + if(!$this->Commande('RCPT TO:<'.$tmp_A.'>', array(250,251), 'Envoie du mail impossible car le serveur n' accèpte pas la commande RCPT TO !!!')){ + return false; + } + } + }else{ + if(!$this->Commande('RCPT TO:<'.$tmp_to.'>', array(250,251), 'Envoie du mail impossible car le serveur n' accèpte pas la commande RCPT TO !!!')){ + return false; + } + } + } + + //********************************************************************** + // On créer les entêtes ( headers ) si c' est pas fait + if(empty($header)){ + if(!$header = $this->headers()){ + $this->erreur .= 'Impossible d' envoyer le mail !!!
    '."\r\n"; + return false; + } + } + + + //********************************************************************** + // On indique que l' on va envoyer des données + if(!$this->Commande('DATA', 354, 'Envoie du mail impossible car le serveur n' accèpte pas la commande DATA!!!')){ + return false; + } + + + //********************************************************************** + // Envoie de l' entête et du message + fputs($this->smtp_connection, $header); + fputs($this->smtp_connection, "\r\n.\r\n"); + + $reponce = $this->get_smtp_data(); + // Debug + if($this->debug){ + echo '
    Entête et message :
    ',"\r\n",'
    ',str_replace(array("\r\n","\n"), '
    ', $header),'
    ',"\r\n",$message,'
    ',"\r\n",'
    ',"\r\n",str_replace("\r\n", '
    ', $reponce['msg']); + } + if($reponce['code'] !== 250 && $reponce['code'] !== 354){ + $this->erreur = 'Envoie du mail impossible !!!
    '."\r\n" + .'Numéro de l' erreur: '.$reponce['code'].'
    '."\r\n" + .'Message renvoyé: '.$reponce['msg'].'
    '."\r\n"; + return false; + } + + + //********************************************************************** + // Variables temporairement modifiées + if($to === $this->To){ + $this->To = ''; + } + if($subject === $this->Sujet){ + $this->Sujet = ''; + } + + //********************************************************************** + // Déconnection automatique + //********************************************************************** + if($auto_disconnect){// Auto déconnection ? + $this->Deconnection_SMTP();// Déconnection + } + + //********************************************************************** + // Mail envoyé + //********************************************************************** + return true; + } + + + //************************************************************************** + // Lecture des données renvoyées par le serveur SMTP + //************************************************************************** + function get_smtp_data(){ + $data = ''; + while($donnees = fgets($this->smtp_connection, 515)){// On parcour les données renvoyées + $data .= $donnees; + + if(substr($donnees,3,1) == ' ' && !empty($data)){break;}// On vérifi si on a toutes les données + } + // Renvoie des données : array(Code, message complet) + return array('code'=>(int)substr($data, 0, 3), 'msg'=>$data); + } + + + //************************************************************************** + // Execution des commandes SMTP + //************************************************************************** + function Commande($commande, $bad_error, $msg_error='', $debug=1){ + if(!empty($this->smtp_connection)){ + fputs($this->smtp_connection, $commande."\n"); + $reponce = $this->get_smtp_data(); + // Debug + if($this->debug && $debug){ + echo '
    ',htmlentities($commande),'
    ',"\r\n",str_replace("\r\n", '
    ', $reponce['msg']); + } + + // Tableau de code valide + if((is_array($bad_error) && !in_array($reponce['code'], $bad_error)) || (!is_array($bad_error) && $reponce['code'] !== $bad_error)){ + if($msg_error){ + $this->erreur = $msg_error.'
    '."\r\n" + .'Numéro de l' erreur: '.$reponce['code'].'
    '."\r\n" + .'Message renvoyé: '.$reponce['msg'].'
    '."\r\n"; + } + if(!$debug){ + return array('no_error'=>false, 'msg'=>$reponce['msg']); + }else{ + return false; + } + } + + if(!$debug){ + return array('no_error'=>true, 'msg'=>$reponce['msg']); + }else{ + return true; + } + }else{ + $this->erreur = 'Impossible d' éxecuter la commande '.$commande.' car il n' y a pas de connection !!!
    '."\r\n"; + if(!$debug){ + return array('no_error'=>false, 'msg'=>''); + }else{ + return false; + } + } + } + + + //************************************************************************** + // Fonction de déconnection SMTP + //************************************************************************** + function Deconnection_SMTP(){ + if(!empty($this->smtp_connection)){ + if(!$this->Commande('QUIT', 221, 'Impossible de se déconnecter !!!')){ + return false; + } + + @sleep(5);// On laisse 5 seconde au serveur pour terminer toutes les instructions + if(!fclose($this->smtp_connection)){ + $this->erreur = 'Impossible de se déconnecter !!!
    '."\r\n"; + return false; + } + $this->smtp_connection = 0; + return true; + } + $this->erreur = 'Impossible de se déconnecter car il n' y a pas de connection !!!
    '."\r\n"; + return false; + } + } + ?> + + diff --git a/class.validator.php b/class.validator.php new file mode 100644 index 0000000..4629005 --- /dev/null +++ b/class.validator.php @@ -0,0 +1,73 @@ + array("regexp" => $reg)); + if (!filter_var($var,$filter,$opts)) { + throw new Exception(_("Field validation does not match ").$msg); + } + } + if ($filter == FILTER_VALIDATE_INT) { + // Fix code code validate 0 as integer (add filter_var === 0) + if (! (filter_var($var,$filter) === 0 || filter_var($var,$filter) )) { + throw new Exception(_("Field validation not an int ").$msg); + } + } + if ($filter == FILTER_VALIDATE_FLOAT) { + if (!filter_var($var,$filter)) { + throw new Exception(_("Field validation not a float ").$msg); + } + } + } + + /** + * + */ + function email($var,$msg) { + $this->validate($var,FILTER_VALIDATE_EMAIL,$msg); + } + + function str_date($var,$msg) { + $date = date_parse($var); + if ($date['error_count'] == 0 && checkdate($date['month'],$date['day'],$date['year'])) + { + return ; + } + throw new Exception(_("Invalide date ").$msg); + } + + /** + * + */ + function str($var,$msg,$reg="/[A-Za-z0-9\-].*/") { + $this->validate($var,FILTER_VALIDATE_REGEXP,$msg,$reg); + } + /** + * + */ + function num_int($var,$msg) { + $this->validate($var,FILTER_VALIDATE_INT,$msg); + } + + /** + * + */ + function num_float($var,$msg) { + $this->validate($var,FILTER_VALIDATE_FLOAT,$msg); + } +} + +?> diff --git a/iface.ActionResult.php b/iface.ActionResult.php new file mode 100644 index 0000000..540b0f0 --- /dev/null +++ b/iface.ActionResult.php @@ -0,0 +1,12 @@ + diff --git a/iface.Request.php b/iface.Request.php new file mode 100644 index 0000000..18e0fe6 --- /dev/null +++ b/iface.Request.php @@ -0,0 +1,45 @@ + diff --git a/monofont.ttf b/monofont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..ec6c51b2640bafbf046060a8e2b594905dd5e7dc GIT binary patch literal 41036 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 SyQDLSP-N_L`0;nd!2ds0@g5HV literal 0 HcmV?d00001 diff --git a/utils.php b/utils.php new file mode 100644 index 0000000..5110f13 --- /dev/null +++ b/utils.php @@ -0,0 +1,18 @@ + -- 2.30.2