public function parse($html) { // replace entities $html = preg_replace('/&([a-z0-9#]{2,5});/i', '+$1;', $html); //before sending to xml parser make sure we have valid xml by tidying it up $html = Kwf_Util_Tidy::repairHtml($html); $this->_stack = array(); $this->_ret = ''; $this->_parser = xml_parser_create(); xml_set_object($this->_parser, $this); xml_set_element_handler($this->_parser, 'startElement', 'endElement'); xml_set_character_data_handler($this->_parser, 'characterData'); xml_set_default_handler($this->_parser, 'characterData'); $result = xml_parse($this->_parser, '<body>' . $html . '</body>', true); if (!$result) { // wenn man ein nicht geschlossenes <br> rein gibt, schreit er hier, // macht aber normal weiter. wenns zu oft vorkommt, evtl. exception // entfernen und ignorieren, oder was andres überlegen :-) $errorCode = xml_get_error_code($this->_parser); $ex = new Kwf_Exception("HtmlExport UrlParser XML Error {$errorCode}: " . xml_error_string($errorCode) . "in line " . xml_get_current_line_number($this->_parser) . " parsed html: " . $html); $ex->logOrThrow(); } // re-replace entities $this->_ret = preg_replace('/\\+([a-z0-9#]{2,5});/i', '&$1;', $this->_ret); return $this->_ret; }
/** * Puts a JavaScript Variable used in Kwf_js/Statistics.js * * @return string */ public function getIncludeCode() { $value = Kwf_Statistics::getDefaultOptValue($this->getData()); $optInShowBox = $this->getData()->getBaseProperty('statistics.optInShowBox'); $html = ''; if ($value == 'out' || $value == 'in' && $optInShowBox) { $components = Kwf_Component_Data_Root::getInstance()->getComponentsByClass('Kwc_Statistics_Opt_Component', array('subroot' => $this->getData())); $url = isset($components[0]) ? $components[0]->url : null; $html = $this->_getOptBoxInnerHtml($url); if (!$html) { $exception = new Kwf_Exception('To disable optbox please change config.'); $exception->logOrThrow(); } $html = '<div class="' . self::getRootElementClass($this) . '"><div class="inner">' . $html . '<div></div>'; $html = str_replace("'", "\\'", $html); } $ret = '<script type="text/javascript">'; //TODO commonjs /* $ret .= "if (typeof Kwf == 'undefined') Kwf = {};"; $ret .= "if (typeof Kwf.Statistics == 'undefined') Kwf.Statistics = {};"; $ret .= "Kwf.Statistics.defaultOptValue = '$value';"; $ret .= "Kwf.Statistics.optBoxHtml = '$html';"; */ $ret .= $this->_getJavascriptIncludeCode(); $ret .= '</script>'; return $ret; }
protected function _beforeSave() { parent::_beforeSave(); //add_component_id darf leer sein, passiert wenn eine bestellung im backend angelegt wird if (!$this->add_component_class) { $e = new Kwf_Exception("add_component_class is required"); $e->logOrThrow(); } }
public function getChildData($parentData, $select = array()) { if (is_array($select)) { $select = new Kwf_Component_Select($select); } if (!$parentData && !$select->hasPart(Kwf_Component_Select::WHERE_CHILD_OF) && !$select->hasPart(Kwf_Component_Select::WHERE_ID)) { $e = new Kwf_Exception("Looking up components generated by List is slow, and must be avoided."); $e->logOrThrow(); } return parent::getChildData($parentData, $select); }
public static function getOpt() { $ret = null; if (isset($_COOKIE[self::$_cookieName])) { $ret = $_COOKIE[self::$_cookieName]; if ($ret != self::OPT_IN && $ret != self::OPT_OUT) { $exception = new Kwf_Exception('stored Cookie must be ' . self::OPT_IN . ' or ' . self::OPT_OUT); $exception->logOrThrow(); } } return $ret; }
public static function getUserOptValue() { if (!isset($_COOKIE[self::$_cookieName])) { return null; } else { $ret = $_COOKIE[self::$_cookieName]; if ($ret != self::OPT_IN && $ret != self::OPT_OUT) { $exception = new Kwf_Exception('stored Cookie must be ' . self::OPT_IN . ' or ' . self::OPT_OUT); $exception->logOrThrow(); return null; } return $ret; } }
public function handle($method = null, $arguments = null, $extraParams = null) { try { if (is_null($method) && isset($_REQUEST['method']) && !is_null($_REQUEST['method'])) { $method = $_REQUEST['method']; } if (is_null($arguments) && isset($_REQUEST['arguments']) && !is_null($_REQUEST['arguments'])) { $arguments = unserialize($_REQUEST['arguments']); } if (is_null($extraParams) && isset($_REQUEST['extraParams']) && !is_null($_REQUEST['extraParams'])) { $extraParams = unserialize($_REQUEST['extraParams']); } if (is_null($arguments)) { $arguments = array(); } // throw some exceptions if (!$this->_handler) { throw new Kwf_Srpc_Exception("A handler has to be set when using 'Kwc_Srpc_Server'"); } if (is_null($method)) { throw new Kwf_Srpc_Exception("'method' must be set as first argument, or exists as key in " . '$_REQUEST'); } if (!is_null($method) && !is_string($method)) { throw new Kwf_Srpc_Exception("'method' is expected to be a string"); } if (!is_null($arguments) && !is_array($arguments)) { throw new Kwf_Srpc_Exception("'arguments' is expected to be an array"); } $handler = $this->getHandler(); if ($extraParams) { $handler->setExtraParams($extraParams); } $result = call_user_func_array(array($handler, $method), $arguments); $result = serialize($result); if (strpos($result, 'Kwf_') !== false) { $ex = new Kwf_Exception("a class name with 'Kwf_' must not be sent through srpc server"); $ex->logOrThrow(); } } catch (Exception $e) { $result = "An exception has been caught occured in Srpc_Server:\n\n" . "Message: " . $e->getMessage() . "\n" . "File: " . $e->getFile() . ':' . $e->getLine() . "\n" . "Trace: \n---=== Trace start ===---\n" . $e->getTraceAsString() . "\n---=== Trace end ===---\n"; } if (!$this->_returnResponse) { echo $result; return; } else { return $result; } }
public function queryEnd($queryId) { if ($queryId == $this->_count) { if ($this->_lastQuery->hasEnded()) { throw new Zend_Db_Profiler_Exception("Query with profiler handle '{$queryId}' has already ended."); } $this->_lastQuery->end(); $time = $this->_lastQuery->getElapsedSecs(); if ($time > $this->_timeout) { $e = new Kwf_Exception('Query timed out with ' . $time . 's. \'' . $this->_lastQuery->getQuery() . '\''); $e->logOrThrow(); } } else { throw new Kwf_Exception('Query not found'); } }
public function getRowBySiblingRow(Kwf_Model_Row_Interface $siblingRow) { $data = $siblingRow->{$this->_fieldName}; if (is_string($data)) { if (substr($data, 0, 13) == 'kwfSerialized') { //früher wurde es mal so gespeichert $data = substr($data, 13); } if (substr($data, 0, 2) == 'a:') { //früher wurde es mal so gespeichert, das 35000 update script sollte es konvertieren //erwischt aber manchmal nicht alles try { $data = unserialize($data); } catch (Exception $e) { $e = new Kwf_Exception($e->getMessage() . " {$data}"); $e->logOrThrow(); $data = false; } } else { // json_decode gibt auch keinen fehler aus, wenn man ihm einen // falschen string (zB serialized) übergibt. bei nicht-json-daten // kommt immer null raus. Da bringt das try-catch eher wenig, // weil null nunmal keine Exception ist. // Lösung: Wir schmeissen die exception händisch im falle von // NULL. Eventuelles PROBLEM dabei ist jedoch, // wenn man: $data = json_decode(json_encode(NULL)) // macht, weil dann korrekterweise NULL rauskommen würde. // deshalb wird dieser fall separat ohne dem json_decode behandelt if ($data == 'null' || $data == '') { $data = null; } else { $decodedData = json_decode($data); if (is_null($decodedData)) { // json_encode hat nicht funktioniert, siehe mörder-kommentar paar zeilen vorher $e = new Kwf_Exception("json_decode failed. Input data was: '{$data}'"); $e->logOrThrow(); } $data = $decodedData; } } } if (!$data) { $data = $this->getDefault(); } $data = (array) $data; return new $this->_rowClass(array('model' => $this, 'siblingRow' => $siblingRow, 'data' => $data)); }
public function getItemIds($count = null, $offset = null) { $select = $this->_getSelect(); if (!$select) { return array(); } if ($count) { if ($select->hasPart(Kwf_Model_Select::LIMIT_COUNT)) { $ex = new Kwf_Exception("Can't use getItemIds with limit in select when \$count paramter is given. You probably should disable paging for {$this->getData()->componentClass}."); $ex->logOrThrow(); } $select->limit($count, $offset); } $itemDirectory = $this->getData()->parent->getComponent()->getItemDirectory(); if (is_string($itemDirectory)) { $c = Kwc_Abstract::getComponentClassByParentClass($itemDirectory); $generator = Kwf_Component_Generator_Abstract::getInstance($c, 'detail'); $items = $generator->getChildIds(null, $select); } else { $items = $itemDirectory->getChildIds($select); } return $items; }
private function _parse($html) { $html = preg_replace('/&([a-z0-9#]{2,5});/i', '+$1;', $html); $html = str_replace('\\n', ' ', $html); $this->_parser = xml_parser_create(); xml_set_object($this->_parser, $this); xml_set_element_handler($this->_parser, '_startElement', '_endElement'); xml_set_character_data_handler($this->_parser, '_characterData'); xml_set_default_handler($this->_parser, '_characterData'); $html = preg_replace('#<kwc(.*?)>#', '{kwc$1}', $html); $this->_ret = ''; $result = xml_parse($this->_parser, "<BODY>" . $html . "</BODY>", true); if (!$result) { // wenn man ein nicht geschlossenes <br> rein gibt, schreit er hier, // macht aber normal weiter. wenns zu oft vorkommt, evtl. exception // entfernen und ignorieren, oder was andres überlegen :-) $errorCode = xml_get_error_code($this->_parser); $ex = new Kwf_Exception("Mail HtmlParser XML Error {$errorCode}: " . xml_error_string($errorCode)); $ex->logOrThrow(); } //replace spaces in links (otherwise there would be a linebreak inside the link after wordwrap) $this->_ret = preg_replace_callback('/{kwc[^}]+}/', create_function('$data', 'return str_replace(" ", "*kwfSpace*", $data[0]);'), $this->_ret); //make a linebreak after 72 chars $this->_ret = wordwrap($this->_ret, 75, "\n", false); //reconstruct spaces inside links $this->_ret = preg_replace_callback('/{kwc[^}]+}/', create_function('$data', 'return str_replace("*kwfSpace*", " ", $data[0]);'), $this->_ret); $this->_ret = preg_replace('#{kwc(.*?)}#', '<kwc$1>', $this->_ret); return $this->_ret; }
public function __call($method, $args) { $log = date('Y-m-d H:i:s') . " (start) {$this->_serverUrl} {$method} " . Kwf_Setup::getRequestPath() . "\n"; file_put_contents('log/srpc-call', $log, FILE_APPEND); $start = microtime(true); $b = Kwf_Benchmark::start('srpc call', $this->_serverUrl . ' ' . $method); $params = array('method' => $method, 'arguments' => array(), 'extraParams' => array()); if (is_array($args) && count($args)) { $params['arguments'] = $args; } if ($this->_extraParams) { $params['extraParams'] = $this->_extraParams; } $params['arguments'] = serialize($params['arguments']); $params['extraParams'] = serialize($params['extraParams']); if (strpos($params['arguments'], 'Kwf_') !== false || strpos($params['extraParams'], 'Kwf_') !== false) { $ex = new Kwf_Exception("a class name with 'Kwf_' must not be sent through srpc client"); $ex->logOrThrow(); } $response = $this->_performRequest($params); $log = date('Y-m-d H:i:s') . ' ' . round(microtime(true) - $start, 2) . "s {$this->_serverUrl} {$method} " . Kwf_Setup::getRequestPath() . "\n"; file_put_contents('log/srpc-call', $log, FILE_APPEND); if ($b) { $b->stop(); } try { $result = unserialize($response); } catch (Exception $e) { throw new Kwf_Exception('Srpc Server Response is not serialized: ' . $response); } if ($result === false) { throw new Kwf_Exception('Srpc Server Response is not serialized: ' . $response); } // result könnte eine Exception sein, wenn ja wird sie weitergeschmissen if ($result instanceof Kwf_Exception_Serializable) { throw $result->getException(); } else { if ($result instanceof Exception) { throw $result; } } return $result; }
private function _checkSingleComponent($components) { if (count($components) > 1) { $ids = array(); foreach ($components as $c) { $ids[] = $c->componentId; } $e = new Kwf_Exception('getComponentByXxx must not get more than one component but got these: ' . implode(', ', $ids)); $e->logOrThrow(); } }
private function _getBufferLogFileName() { if (!isset($this->_bufferLogFileName)) { if (Kwf_Config::getValue('debug.dbBuffer')) { foreach (glob('cache/model/db-buffer-*') as $i) { $time = (int) substr($i, 15); if (time() - $time > 15) { $bufferSize = file_get_contents($i); $e = new Kwf_Exception("Not written import buffer with size '{$bufferSize}' found (age: " . (time() - $time) . "): '{$i}'"); $e->logOrThrow(); } } $this->_bufferLogFileName = 'cache/model/db-buffer-' . time() . '-' . uniqid(); } else { $this->_bufferLogFileName = false; } } return $this->_bufferLogFileName; }
public static function executeJobs($jobFrequency, $debug) { foreach (self::getAllMaintenanceJobs() as $job) { if ($job->getFrequency() == $jobFrequency) { if ($debug) { echo "executing " . get_class($job) . "\n"; } $maxTime = $job->getMaxTime(); $t = microtime(true); if ($jobFrequency == Kwf_Util_Maintenance_Job_Abstract::FREQUENCY_DAILY || $jobFrequency == Kwf_Util_Maintenance_Job_Abstract::FREQUENCY_HOURLY) { $cmd = "php bootstrap.php maintenance-jobs run-job --job=" . escapeshellarg(get_class($job)); if ($debug) { $cmd .= " --debug"; } $descriptorspec = array(); $pipes = array(); $process = proc_open($cmd, $descriptorspec, $pipes); if (!is_resource($process)) { $e = new Kwf_Exception("Couldn't start maintenance job " . get_class($job)); $e->logOrThrow(); continue; } $retVar = null; while (true) { $status = proc_get_status($process); if (!$status['running']) { $retVar = $status['exitcode']; break; } if (microtime(true) - $t > $maxTime * 2) { //when jobs runs maxTime twice kill it file_put_contents('php://stderr', "\nWARNING: Killing maintenance-jobs process (running > maxTime*2)...\n"); proc_terminate($process); break; } sleep(1); } proc_close($process); if ($retVar) { $e = new Kwf_Exception("Maintenance job " . get_class($job) . " failed with exit code {$retVar}"); $e->logOrThrow(); } } else { try { $job->execute($debug); } catch (Exception $e) { file_put_contents('php://stderr', $e->toString() . "\n"); if (!$e instanceof Kwf_Exception_Abstract) { $e = new Kwf_Exception_Other($e); } $e->logOrThrow(); } } $t = microtime(true) - $t; if ($debug) { echo "executed " . get_class($job) . " in " . round($t, 3) . "s\n"; } if ($t > $maxTime) { $msg = "Maintenance job " . get_class($job) . " took " . round($t, 3) . "s to execute which is above the limit of {$maxTime}."; file_put_contents('php://stderr', $msg . "\n"); $e = new Kwf_Exception($msg); $e->logOrThrow(); } if ($debug) { echo "\n"; } } } }
/** * Returns variables that can be used in Component.tpl * @param e.g. for accessing recipient in Mail_Renderer * @return array */ public function getTemplateVars(Kwf_Component_Renderer_Abstract $renderer) { $ret = array(); $ret['placeholder'] = $this->_getPlaceholder(); $ret['rootElementClass'] = self::getRootElementClass($this); $ret['bemClass'] = $this->_getBemClass(''); $ret['data'] = $this->getData(); $ret['row'] = $this->_getRow(); $supportedContexts = Kwf_Component_Layout_Abstract::getInstance($this->getData()->componentClass)->getSupportedContexts(); if ($supportedContexts) { $contexts = Kwf_Component_Layout_Abstract::getInstance($this->getData()->componentClass)->getContexts($this->getData()); if (is_null($contexts)) { $e = new Kwf_Exception("Didn't get layout contexts for " . $this->getData()->componentId); $e->logOrThrow(); } foreach ($contexts as $ctx) { if (!in_array($ctx, $supportedContexts)) { $e = new Kwf_Exception("Master Layout Context " . json_encode($ctx) . " is not supported by " . $this->getData()->componentClass . " for '" . $this->getData()->componentId . "'"); $e->logOrThrow(); } } } return $ret; }
public function getTemplateVars() { $ex = new Kwf_Exception(get_class($this) . ' must only be used as a page type.'); $ex->logOrThrow(); return parent::getTemplateVars(); }
public function startAction() { $this->_helper->viewRenderer->setNoRender(true); $model = Kwf_Model_Abstract::getInstance('Kwc_Newsletter_Model'); $procs = array(); while (true) { $select = $model->select()->where(new Kwf_Model_Select_Expr_Or(array(new Kwf_Model_Select_Expr_Equal('status', 'start'), new Kwf_Model_Select_Expr_And(array(new Kwf_Model_Select_Expr_Equal('status', 'startLater'), new Kwf_Model_Select_Expr_LowerEqual('start_date', new Kwf_DateTime(time())))), new Kwf_Model_Select_Expr_Equal('status', 'sending')))); $rows = $model->getRows($select); $activeCountRows = count($rows); foreach ($rows as $newsletterRow) { if ($newsletterRow->status != 'sending') { $newsletterRow->resume_date = date('Y-m-d H:i:s'); $newsletterRow->status = 'sending'; $newsletterRow->save(); } if (!isset($procs[$newsletterRow->id])) { $procs[$newsletterRow->id] = array(); } //remove stopped processes (might stop because of memory limit or simply crash for some reason) foreach ($procs[$newsletterRow->id] as $k => $p) { if (!$p->isRunning()) { if ($this->_getParam('debug')) { echo "process " . $p->getPid() . " stopped...\n"; } unset($procs[$newsletterRow->id][$k]); } } $s = new Kwf_Model_Select(); $s->whereEquals('newsletter_id', $newsletterRow->id); $s->whereNull('send_process_pid'); if (!$newsletterRow->getModel()->getDependentModel('Queue')->countRows($s)) { $newsletterRow->status = 'finished'; $newsletterRow->save(); if ($this->_getParam('debug')) { echo "Newsletter finished.\n"; } //give send processes time to finish sleep(5); //delete "hanging" queue entries $s = new Kwf_Model_Select(); $s->whereEquals('newsletter_id', $newsletterRow->id); foreach ($newsletterRow->getModel()->getDependentModel('Queue')->getRows($s) as $queueRow) { $newsletterRow->getModel()->getDependentModel('QueueLog')->createRow(array('newsletter_id' => $queueRow->newsletter_id, 'recipient_model' => $queueRow->recipient_model, 'recipient_id' => $queueRow->recipient_id, 'status' => 'failed', 'send_date' => date('Y-m-d H:i:s')))->save(); $msg = "Newsletter finished but queue entry with pid {$queueRow->send_process_pid} still exists: {$queueRow->recipient_id} {$queueRow->searchtext}"; $e = new Kwf_Exception($msg); $e->logOrThrow(); echo $msg . "\n"; $queueRow->delete(); } continue; } if ($this->_getParam('debug')) { echo count($procs[$newsletterRow->id]) . " running processes\n"; } $numOfProcesses = 1; if ($newsletterRow->mails_per_minute == 'unlimited') { $numOfProcesses = $this->_getParam('maxProcesses'); if (!$numOfProcesses) { $numOfProcesses = 3; } } while (count($procs[$newsletterRow->id]) < $numOfProcesses) { $cmd = "php bootstrap.php newsletter send --newsletterId={$newsletterRow->id}"; if ($this->_getParam('debug')) { $cmd .= " --debug"; } if ($this->_getParam('benchmark')) { $cmd .= " --benchmark"; } if ($this->_getParam('verbose')) { $cmd .= " --verbose"; } $descriptorspec = array(1 => STDOUT, 2 => STDERR); $p = new Kwf_Util_Proc($cmd, $descriptorspec); $procs[$newsletterRow->id][] = $p; if ($this->_getParam('debug')) { echo "\n*** started new process with PID " . $p->getPid() . "\n"; echo $cmd . "\n"; } sleep(3); //don't start all processes at the same time } if ($this->_getParam('debug')) { echo "Newletter {$newsletterRow->id}: currently sending with " . round($newsletterRow->getCurrentSpeed()) . " mails/min\n"; } } Kwf_Model_Abstract::clearAllRows(); if ($this->_getParam('debug')) { echo "sleep 10 secs.\n"; } sleep(10); } }
public function getTemplateVars(Kwf_Component_Renderer_Abstract $renderer) { $ex = new Kwf_Exception(get_class($this) . ' must only be used as a page type.'); $ex->logOrThrow(); return parent::getTemplateVars($renderer); }