public function indexAjax() { $where = array(); $bindings = array(); $params = Input::requireParams('package', 'package_version', 'brand', 'phone_model', 'product', 'os_version', 'country'); // package if ($params->package !== '') { $a = explode(',', $params->package); $vals = array(); foreach ($a as $val) { $vals[] = "s.package_name = ?"; $bindings[] = $val; } $vals = '(' . implode(' OR ', $vals) . ')'; $where[] = $vals; } // package_version if ($params->package_version !== '') { $a = explode(',', $params->package_version); $vals = array(); foreach ($a as $val) { $vals[] = "s.app_version_name = ?"; $bindings[] = $val; } $vals = '(' . implode(' OR ', $vals) . ')'; $where[] = $vals; } // brand if ($params->brand !== '') { $a = explode(',', $params->brand); $vals = array(); foreach ($a as $val) { $vals[] = "s.brand = ?"; $bindings[] = $val; } $vals = '(' . implode(' OR ', $vals) . ')'; $where[] = $vals; } // phone_model if ($params->phone_model !== '') { $a = explode(',', $params->phone_model); $vals = array(); foreach ($a as $val) { $vals[] = "s.phone_model = ?"; $bindings[] = $val; } $vals = '(' . implode(' OR ', $vals) . ')'; $where[] = $vals; } // product if ($params->product !== '') { $a = explode(',', $params->product); $vals = array(); foreach ($a as $val) { $vals[] = "s.product = ?"; $bindings[] = $val; } $vals = '(' . implode(' OR ', $vals) . ')'; $where[] = $vals; } // os_version if ($params->os_version !== '') { $a = explode(',', $params->os_version); $vals = array(); foreach ($a as $val) { $vals[] = "s.android_version = ?"; $bindings[] = $val; } $vals = '(' . implode(' OR ', $vals) . ')'; $where[] = $vals; } // country if ($params->country !== '') { $a = explode(',', $params->country); $vals = array(); foreach ($a as $val) { $vals[] = "s.country = ?"; $bindings[] = $val; } $vals = '(' . implode(' OR ', $vals) . ')'; $where[] = $vals; } if (sizeof($where) == 0) { $where = '1'; } else { $where = implode(' AND ', $where); } $query = "\n\t\t\tSELECT\n\t\t\t\ts.id,\n\t\t\t\ts.created_at,\n\t\t\t\ts.package_name,\n\t\t\t\ts.app_version_name as package_version,\n\t\t\t\ts.brand,\n\t\t\t\ts.phone_model,\n\t\t\t\ts.product,\n\t\t\t\ts.android_version,\n\t\t\t\ts.country,\n\t\t\t\ts.stack_trace\n\t\t\tFROM\n\t\t\t\tcrash_submit s\n\t\t\tWHERE\n\t\t\t\t{$where}\n\t\t\tORDER BY s.created_at DESC\n\t\t\tLIMIT 0, 50\n\t\t"; $records = Db::getAdapter()->query($query, $bindings); $data = array(); foreach ($records as $r) { if ($r->stack_trace !== null) { $lines = explode("\n", $r->stack_trace); $stackTraceSummary = array(); $more = 0; foreach ($lines as $line) { $ord = ord(substr($line, 0, 1)); if ($ord >= 65 && $ord <= 90 || $ord >= 97 && $ord <= 122) { if (sizeof($stackTraceSummary) < 2) { $stackTraceSummary[] = trim($line); } else { $more++; } } } if ($more > 0) { $stackTraceSummary[] = "... and {$more} more line(s)"; } $stackTraceSummary = implode("\n", $stackTraceSummary); } else { $stackTraceSummary = null; } $data[] = array('id' => (int) $r->id, 'created_at' => Misc::userDate('H:i:s', $r->created_at), 'package' => "{$r->package_name} {$r->package_version}", 'device' => "{$r->brand}<br/>{$r->phone_model}", 'product' => $r->phone_model != $r->product ? $r->product : null, 'os' => "Android {$r->android_version}", 'country' => $r->country, 'stack_trace' => $stackTraceSummary); } return Json::create(array('success' => true, 'time' => Misc::userDate('Y-m-d H:i:s'), 'data' => $data)); }
/** * Save this initialized object into database. * * @return integer how many rows is affected */ public function save() { $data = $this->getData(); $originalData = $this->originalData; $toUpdate = array(); foreach ($data as $field => $value) { if (isset($originalData[$field]) || $originalData[$field] === null) { if ($value !== $originalData[$field]) { $toUpdate[$field] = $value; } } else { $toUpdate[$field] = $value; } } if (sizeof($toUpdate) > 0) { if (!is_array(static::$primaryKey)) { if (isset($originalData[static::$primaryKey])) { // we have pk value, so lets update $update = new Update(static::getTableName()); $update->setValues($toUpdate); if (!is_array(static::$primaryKey)) { $update->where(static::$primaryKey, $data[static::$primaryKey]); } else { foreach (static::$primaryKey as $field) { $update->where($field, $data[$field]); } } try { $result = $update->exec(static::$connection); } catch (Exception $e) { $result = false; } if ($result !== false) { $this->originalData = $this->data; } return $result; } else { // we don't have pk value, so lets insert $insert = new Insert(static::getTableName()); $insert->add($toUpdate); try { $insert->exec(static::$connection); } catch (Exception $e) { return false; } $this->data[static::$primaryKey] = Db::getAdapter(static::$connection)->getLastInsertId(); $this->originalData = $this->data; } } else { // TODO: Implementirati multiple key throw new Exception('Multiple primary key not implemented'); } } return true; }
/** * (non-PHPdoc) * @see \Koldy\Log\Writer\AbstractLogWriter::logMessage() */ protected function logMessage($level, $message) { if ($this->inserting) { return; } $data = $this->getFieldsData($level, $message); if ($data !== false) { if (in_array($level, $this->config['log'])) { $this->inserting = true; $insert = new Insert($this->config['table']); $insert->add($data); if ($insert->exec($this->config['connection']) === false) { $adapter = KoldyDb::getAdapter($this->config['connection']); // do not process this with Log::exception because it will run into recursion $this->detectEmailAlert('exception'); $this->appendMessage(date('Y-m-d H:i:sO') . "\tERROR inserting log message into database: {$adapter->getLastError()}\n\n{$adapter->getLastException()->getTraceAsString()}\n"); } } $this->inserting = false; $this->detectEmailAlert($level); $this->appendMessage(date('Y-m-d H:i:sO') . "\t" . implode("\t", array_values($data)) . "\n"); } }
/** * Process the request * @param string $os 'Android','iOS' or 'Windows' * * TODO: This logic shouldn't be in the model */ public static function processRequest($os) { if (!isset($_POST['PACKAGE_NAME'])) { Log::warning('Package name is not set! UAS=' . Request::userAgent() . ' POST=' . Json::encode($_POST)); } $time = time(); $ip = $_SERVER['REMOTE_ADDR']; $host = gethostbyaddr($ip); $country = null; $provider = null; if ($host != $ip && strpos($host, '.') !== false) { $country = strtolower(substr($host, strrpos($host, '.') + 1)); if (strlen($country) != 2) { $country = null; } $provider = \Provider::normalizeHostName($host); } Log::notice("Got request time={$time} host={$host} country={$country}"); $values = array('created_at', 'package_name', 'app_version_code', 'app_version_name', 'brand', 'phone_model', 'product', 'stack_trace', 'android_version', 'file_path', 'total_mem_size', 'available_mem_size', 'user_comment', 'user_app_start_date', 'user_crash_date', 'installation_id', 'report_id', 'user_email'); $data = array(); $vals = $_POST; foreach ($values as $key) { $key = strtoupper($key); if (isset($vals[$key])) { $data[$key] = trim($vals[$key]); unset($vals[$key]); } } if (isset($data['user_email']) && ($data['user_email'] == 'N/A' || trim($data['user_email']) == '')) { $data['user_email'] = null; } $data['created_at'] = gmdate('Y-m-d H:i:s'); $data['country'] = $country; $data['provider'] = $provider; $data['os'] = $os; $secureCount = 0; do { $submit = static::create($data); if ($submit === false) { Db::getAdapter()->close(); Log::info("Failed to insert crash submit report for time={$time}, waiting 5 seconds"); set_time_limit(60); sleep(5); Db::getAdapter()->reconnect(); Log::info("Retry {$secureCount} insert crash submit report for time={$time}"); } } while ($submit === false && $secureCount++ < 3); if ($submit !== false) { foreach ($vals as $metaName => $metaValue) { if ($metaValue !== null) { $metaValue = trim($metaValue); if (strlen($metaValue) > 0) { $secureCount = 0; do { $dbMeta = $submit->insertMeta(strtolower($metaName), trim($metaValue)); if ($dbMeta === false) { Db::getAdapter()->close(); Log::info("Failed to insert submit meta for meta={$metaName} time={$time}, waiting 5 seconds"); set_time_limit(60); sleep(5); Db::getAdapter()->reconnect(); Log::info("Retry {$secureCount} meta insert for meta={$metaName} time={$time}"); } } while ($dbMeta === false && $secureCount++ < 2); } } } } \Email\Trigger::processRequest($_POST); Log::notice("Done request time={$time}"); }
/** * Execute the query * * @param string|\Koldy\Db\Adapter $adapter [optional] execute this query on which adapter? * @throws \Koldy\Exception * @return array|int number of affected rows or array of resultset returned by database */ public function exec($adapter = null) { $query = $this->getQuery(); if ($query === null) { throw new Exception('SQL not built, can not execute query'); } if ($adapter === null) { $adapter = $this->getAdapter(); } else { if (is_string($adapter)) { $adapter = Db::getAdapter($adapter); } else { if ($adapter instanceof Adapter) { // then its fine, don't do anything, just continue } else { throw new Exception('Invalid DB adapter'); } } } return $adapter->query($query, $this->getBindings()); }