public function isFlooding() { $uid = GWF_Session::getUserID(); $uname = GWF_Shoutbox::generateUsername(); $euname = GDO::escape($uname); $table = GDO::table('GWF_Shoutbox'); $max = $uid === 0 ? $this->module->cfgMaxPerDayGuest() : $this->module->cfgMaxPerDayUser(); // $cut = GWF_Time::getDate(GWF_Time::LEN_SECOND, time()-$this->module->cfgTimeout()); // $cnt = $table->countRows("shout_uname='$euname' AND shout_date>'$cut'"); # Check captcha if ($this->module->cfgCaptcha()) { require_once GWF_CORE_PATH . 'inc/3p/Class_Captcha.php'; if (!PhpCaptcha::Validate(Common::getPostString('captcha'), true)) { return GWF_HTML::err('ERR_WRONG_CAPTCHA'); } } # Check date $timeout = $this->module->cfgTimeout(); $last_date = $table->selectVar('MAX(shout_date)', "shout_uid={$uid} AND shout_uname='{$euname}'"); $last_time = $last_date === NULL ? 0 : GWF_Time::getTimestamp($last_date); $next_time = $last_time + $timeout; if ($last_time + $timeout > time()) { return $this->module->error('err_flood_time', array(GWF_Time::humanDuration($next_time - time()))); } # Check amount $today = GWF_Time::getDate(GWF_Date::LEN_SECOND, time() - $timeout); $count = $table->countRows("shout_uid={$uid} AND shout_date>='{$today}'"); if ($count >= $max) { return $this->module->error('err_flood_limit', array($max)); } # All fine return false; }
private function templateUsers($term = '') { $ipp = $this->module->cfgIPP(); $form = $this->getFormQuick(); $usertable = GDO::table('GWF_User'); $by = Common::getGet('by', ''); $dir = Common::getGet('dir', ''); $orderby = $usertable->getMultiOrderby($by, $dir); if ($term === '') { $users = array(); $page = 1; $nPages = 0; } else { $eterm = GDO::escape($term); $deleted = GWF_User::DELETED; $conditions = "user_name LIKE '%{$eterm}%' AND user_options&{$deleted}=0"; $nItems = $usertable->countRows($conditions); $nPages = GWF_PageMenu::getPagecount($ipp, $nItems); $page = Common::clamp(intval(Common::getGet('page', 1)), 1, $nPages); $from = GWF_PageMenu::getFrom($page, $ipp); $users = $usertable->selectObjects('*', $conditions, $orderby, $ipp, $from); } $href_pagemenu = GWF_WEB_ROOT . 'index.php?mo=Usergroups&me=Search&term=' . urlencode($term) . '&by=' . urlencode($by) . '&dir=' . urlencode($dir) . '&page=%PAGE%'; $tVars = array('form' => $form->templateX(false, false), 'users' => $users, 'sort_url' => GWF_WEB_ROOT . 'index.php?mo=Usergroups&me=Search&term=' . urlencode($term) . '&by=%BY%&dir=%DIR%&page=1', 'page_menu' => GWF_PageMenu::display($page, $nPages, $href_pagemenu), 'href_adv' => $this->module->getMethodURL('SearchAdv')); return $this->module->templatePHP('search.php', $tVars); }
public static function getByName($name, $user = true) { if ($user === true) { $user = GWF_Session::getUser(); } $uid = $user->getID(); $name = GDO::escape($name); return self::table(__CLASS__)->selectFirst('1', "pmf_name='{$name}' AND pmf_uid={$uid}") !== false; }
public static function getFailedData(GWF_User $user, $time) { $ip = GDO::escape(GWF_IP6::getIP(GWF_IP_EXACT)); $cut = time() - $time; if (false === ($result = GDO::table(__CLASS__)->selectFirst('COUNT(*) c, MIN(logfail_time) min', "logfail_ip='{$ip}' AND logfail_time>{$cut}"))) { return array(0, 0); } return array((int) $result['c'], (int) $result['min']); }
private static function deletePlayer(SR_Player $player) { $epname = GDO::escape($player->getName()); if (false === GDO::table('SR_BazarShop')->deleteWhere("sr4bs_pname='{$epname}'")) { return false; } if (false === GDO::table('SR_BazarItem')->deleteWhere("sr4ba_pname='{$epname}'")) { return false; } }
/** * Get the player for a join request. * @param SR_Player $leader * @param SR_Clan $clan * @param string $pname * @return SR_Player */ public static function getRequest(SR_Player $leader, SR_Clan $clan, $pname) { $ename = GDO::escape($pname); if (false === ($pid = self::table(__CLASS__)->selectVar('sr4cr_pid', "sr4cr_pname='{$ename}'"))) { return false; } if (false === ($player = Shadowrun4::getPlayerByPID($pid))) { if (false === ($player = SR_Player::getByID($pid))) { return false; } } return $player; }
private static function calcMaps(GDO_Database $db_from, GDO_Database $db_to, array &$db_offsets, $prefix, $prevar) { $classname = 'GWF_ForumBoard'; $db_offsets[$classname] = array(); GDO::setCurrentDB($db_from); $table_from = GDO::table($classname); if (false === ($result = $table_from->select('*', '', 'board_bid ASC'))) { echo GWF_HTML::err('ERR_DATABASE', array(__FILE__, __LINE__)); return false; } GDO::setCurrentDB($db_to); $table_to = GDO::table($classname); while (false !== ($row = $table_from->fetch($result, GDO::ARRAY_A))) { $bid_from = $row['board_bid']; $title_from = $row['board_title']; $etitle_from = GDO::escape($title_from); if (false !== ($oldbid = $table_to->selectVar('board_bid', "board_title='{$etitle_from}'"))) { $db_offsets[$classname][$bid_from] = $oldbid; echo "BID {$bid_from} => {$oldbid}\n"; $table_to->update("board_postcount = board_postcount + {$row['board_postcount']}", "board_bid = {$oldbid}"); $table_to->update("board_threadcount = board_threadcount + {$row['board_threadcount']}", "board_bid = {$oldbid}"); } else { if ($row['board_pid'] > 0) { $row['board_bid'] = '0'; $row['board_pid'] |= 0x40000000; // PID HAS TO GET CONVERTED after this run $row['board_gid'] = $db_offsets['GWF_Group'][$row['board_gid']]; $row['board_pos'] = $table_to->selectVar('COUNT(*)') + 1; $table_to->insertAssoc($row); $newbid = $db_to->insertID(); $db_offsets[$classname][$bid_from] = $newbid; echo "BID {$bid_from} => {$newbid}\n"; } else { $db_offsets[$classname][$bid_from] = $oldbid; echo "BID {$bid_from} => {$oldbid}\n"; $table_to->update("board_postcount = board_postcount + {$row['board_postcount']}", "board_pid = 0"); $table_to->update("board_threadcount = board_threadcount + {$row['board_threadcount']}", "board_pid = 0"); } } } $table_from->free($result); return true; }
private static function insertTag($tag, $pid, $langid) { # Insert tagname $etag = GDO::escape($tag); $langid = (int) $langid; if (false === ($tid = GDO::table(__CLASS__)->selectVar('ptag_tid', "ptag_tag='{$etag}' AND ptag_lang={$langid}"))) { $newtag = new self(array('ptag_tid' => '0', 'ptag_lang' => $langid, 'ptag_tag' => $tag, 'ptag_count' => '1')); if (false === $newtag->insert()) { return GWF_Error::err('ERR_DATABASE', array(__FILE__, __LINE__)); } if (0 == ($tid = $newtag->getID())) { return GWF_Error::err('ERR_DATABASE', array(__FILE__, __LINE__)); } } # Insert into map $data = array('ptm_pid' => $pid, 'ptm_tid' => $tid); if (false === GDO::table('GWF_PageTagMap')->insertAssoc($data, true)) { return GWF_Error::err('ERR_DATABASE', array(__FILE__, __LINE__)); } return true; }
private function onSearch() { $form = $this->formSearch(); if (false !== ($error = $form->validate($this->module))) { return $error . $this->templateSearch(); } $ipp = self::IPP; $term = $form->getVar('searchterm'); $tagname = NULL; $table = GDO::table('Slay_Song'); $whitelist = array('(ss_lyrics>0)', '(ss_options&1)', '(ss_sid_path!=NULL)'); $joins = array('lyrics'); if (false === ($where = GWF_QuickSearch::getQuickSearchConditions($table, array('ss_artist', 'ss_title', 'ss_composer'), $term))) { return GWF_HTML::err('ERR_SEARCH_TERM') . $this->templateSearch(); } $term2 = GDO::escape($term); // $term2 = str_replace(array('%', '_'), array('\\%', '\\_'), $term); $term3 = '1'; if ('0' !== ($tag = $form->getVar('searchtag'))) { $tagname = Slay_Tag::getNameByID($tag); $term3 = 'sst_count>0'; $joins[] = 'searchtag'; } $where = "(({$where}) OR (ssl_lyrics LIKE '%{$term2}%')) AND ({$term3})"; $nItems = $table->countRows($where, $joins); $nPages = GWF_PageMenu::getPagecount($ipp, $nItems); $page = Common::clamp(Common::getGetInt('page'), 1, $nPages); $from = GWF_PageMenu::getFrom($page, $ipp); $by = Common::getGetString('by', self::BY); $dir = Common::getGetString('dir', self::DIR); $orderby = $table->getMultiOrderby($by, $dir, false, $whitelist); $matches = $table->selectAll('*', $where, $orderby, $joins, $ipp, $from, GDO::ARRAY_O); $headers = array(array(), array($this->module->lang('L'), '(ss_lyrics>0)'), array($this->module->lang('T'), 'ss_taggers'), array($this->module->lang('D'), '(ss_options&1)'), array($this->module->lang('th_artist'), 'ss_artist'), array($this->module->lang('th_title'), 'ss_title'), array($this->module->lang('th_duration'), 'ss_duration'), array($this->l('th_bpm'), 'ss_bpm'), array($this->l('th_key'), 'ss_key')); if ($tag > 0) { $headers[] = array($this->module->lang(Slay_Tag::getNameByID($tag)), 'sst_count'); } $headers[] = array($this->module->lang('th_tags')); $tVars = array('form' => $form->templateX($this->module->lang('ft_search'), GWF_WEB_ROOT . 'index.php'), 'pagemenu' => GWF_PageMenu::display($page, $nPages, GWF_WEB_ROOT . sprintf('index.php?mo=Slaytags&me=Search&searchterm=%s&searchtag=%s&by=%s&dir=%s&page=%%PAGE%%', urlencode($term), $tag, urlencode($by), urlencode($dir))), 'matches' => $matches, 'sort_url' => GWF_WEB_ROOT . sprintf('index.php?mo=Slaytags&me=Search&searchterm=%s&searchtag=%s&by=%%BY%%&dir=%%DIR%%&page=1', urlencode($term), $tag), 'is_admin' => GWF_User::isStaffS(), 'headers' => $headers, 'singletag' => $tagname, 'no_match' => count($matches) === 0); return $this->module->template('search.tpl', $tVars); }
public function execute() { GWF_Website::plaintext(); if (false === ($datestamp = Common::getGet('datestamp'))) { return 'TRY ?datestamp=YYYYMMDDHHIISS&limit=5'; } if (strlen($datestamp) !== 14) { return 'TRY ?datestamp=YYYYMMDDHHIISS&limit=5'; } if (0 === ($limit = Common::getGetInt('limit', 0))) { return 'TRY ?datestamp=YYYYMMDDHHIISS&limit=5'; } $date = GDO::escape($datestamp); $limit = Common::clamp($limit, 1, 25); if (false === ($result = GDO::table('GWF_ForumThread')->selectObjects('*', "thread_lastdate>='{$date}' AND thread_options&4=0", 'thread_lastdate DESC', $limit))) { return GWF_HTML::lang('ERR_DATABASE', __FILE__, __LINE__); } $back = ''; $unknown = GWF_HTML::lang('unknown'); foreach (array_reverse($result) as $thread) { #timestamp::lock::postid::threadid::posturl::userurl::username::title $thread instanceof GWF_ForumThread; $locked = $thread->getVar('thread_gid') === '0' ? '0' : '1'; $back .= $thread->getVar('thread_tid'); $back .= '::'; $back .= $thread->getVar('thread_lastdate'); $back .= '::'; $back .= $thread->getVar('thread_gid'); $back .= '::'; $back .= 'https://' . GWF_DOMAIN . $thread->getLastPageHREF($locked === '1'); $back .= '::'; $back .= $locked === '1' ? $unknown : $this->getLastPosterName($thread); $back .= '::'; $back .= $locked === '1' ? $unknown : $thread->getVar('thread_title'); $back .= PHP_EOL; } return $back; }
public function hookRenameUser(GWF_User $user, array $args) { list($oldname, $newname) = $args; $newname = GDO::escape($newname); $uid = $user->getID(); $sid = WC_Site::getWeChall()->getID(); return GDO::table('WC_RegAt')->update("regat_onsitename='{$newname}'", "regat_uid={$uid} AND regat_sid={$sid}"); }
/** * Set options that may be set by the owner of the root page, like group and stuff. * @param GWF_Page $page * @param string $gstring * @return boolean */ private function setRootOptions(GWF_Page $page, $gstring) { $pages = GDO::table('GWF_Page'); $bits = GWF_Page::LOGIN_REQUIRED | GWF_Page::SHOW_TRANS | GWF_Page::SHOW_SIMILAR | GWF_Page::SHOW_MODIFIED; $page->setOption($bits, false); $otherid = $page->getOtherID(); # Kill all bits. $bits = ~$bits; if (false === $pages->update("page_options=page_options&{$bits}", "page_otherid={$otherid}")) { return false; } # Set the new bits. $bits = 0; $bits |= isset($_POST['noguests']) ? GWF_Page::LOGIN_REQUIRED : 0; $bits |= isset($_POST['show_similar']) ? GWF_Page::SHOW_SIMILAR : 0; $bits |= isset($_POST['show_modified']) ? GWF_Page::SHOW_MODIFIED : 0; $bits |= isset($_POST['show_trans']) ? GWF_Page::SHOW_TRANS : 0; $page->setOption($bits, true); $page->setVar('page_groups', $gstring); $gstring = GDO::escape($gstring); # Fire the sql return GDO::table('GWF_Page')->update("page_groups='{$gstring}', page_options=page_options|{$bits}", "page_otherid={$otherid}"); }
public static function validateSolution3($code) { $code = strtolower($code); if (false === ($playername = Common::substrUntil($code, '!', false))) { return -1; } $solution = self::getSolution3($playername); if ($code !== $solution) { return 0; } $table = GDO::table(__CLASS__); $epname = GDO::escape($playername); if (false !== ($row = $table->selectFirst('1', "csl_player='{$epname}' AND csl_cnum=3"))) { return -2; } if (false === $table->insertAssoc(array('csl_player' => $playername, 'csl_cnum' => 3, 'csl_date' => GWF_Time::getDate(GWF_Date::LEN_SECOND)))) { return -3; } return 1; }
private static function helpRace($race) { $base = SR_Player::$RACE_BASE[$race]; $bonus = SR_Player::$RACE[$race]; $out = array(); foreach ($base as $k => $v) { $out[$k] = array(0, 0); } foreach ($bonus as $k => $v) { $out[$k] = array(0, 0); } foreach ($base as $k => $v) { $out[$k] = array($v, $v); } foreach ($bonus as $k => $v) { $out[$k][1] += $v; } unset($out['height']); unset($out['age']); unset($out['bmi']); $erace = GDO::escape($race); $pop = GDO::table('SR_Player')->selectVar('COUNT(*)', "sr4pl_race='{$erace}'"); $back = sprintf(', Population(%d)', $pop); foreach ($out as $k => $data) { $back .= sprintf(', %s: %s(%s)', $k, $data[0], $data[1]); } return sprintf(' Stats: %s.', substr($back, 2)); }
/** * Get a regat row by onsitename. * @param int $siteid * @param string $onsitename * @return WC_RegAt */ public static function getByOnsitename($siteid, $onsitename) { $siteid = (int) $siteid; $onsitename = GDO::escape($onsitename); return self::table(__CLASS__)->selectFirstObject('*', "regat_sid={$siteid} AND regat_onsitename='{$onsitename}'"); }
function merge_user_name($oldname, GDO $to_users, $prefix, $prevar) { // Try with prefix $oldname = $prefix . $oldname; $eoldname = GDO::escape($oldname); if (false === $to_users->selectVar('1', "user_name='{$eoldname}'")) { return $oldname; } // Try with prevar $oldname = $prevar . $oldname; $eoldname = GDO::escape($oldname); if (false === $to_users->selectVar('1', "user_name='{$eoldname}'")) { return $oldname; } // now while with numbers $n = 2; while (true) { $name = $oldname . $n; $eoldname = GDO::escape($name); if (false === $to_users->selectVar('1', "user_name='{$eoldname}'")) { return $name; } $n++; } }
public static function getEMail(GWF_AuditLog $log) { $username = GDO::escape($log->getVar('al_eusername')); return self::table(__CLASS__)->selectVar('am_email', "am_username='******'"); }
/** * Create a WHERE clause from fields and searchterm. * This function does not sanitize the fields anymore! * @param GDO $gdo * @param array $fields * @param string $term * @return string the where clause */ public static function getQuickSearchConditions(GDO $gdo, array $fields, $term) { $term = trim($term); if (false === ($tokens = self::search_tokenize($term))) { GWF_Website::addDefaultOutput(GWF_HTML::err('ERR_GENERAL', array(__FILE__, __LINE__))); return false; } # Whitelist fields // foreach ($fields as $field) // { // if (false === $gdo->getWhitelistedBy($field)) // { // GWF_Website::addDefaultOutput(GWF_HTML::err('ERR_GENERAL', array(__FILE__, __LINE__))); // return false; // } // } # Concat the Fields, (we are doing a full search anyway) $concat = 'CONCAT(' . implode(', ":", ', $fields) . ')'; $prev = array(self::SEARCH_EMPTY, ''); $prevnot = false; $where = array(); foreach ($tokens as $token) { $type = $token[0] & self::SEARCH_TYPE; $not = ($token[0] & self::SEARCH_NOT) > 0; $sql = $token[1]; $setprev = true; switch ($type) { case self::SEARCH_TERM: switch ($prev[0]) { case self::SEARCH_BRACKET_CLOSE: case self::SEARCH_TERM: // break; // break; default: $where[] = 'AND'; case self::SEARCH_EMPTY: $not = $prevnot ? ' NOT' : ''; $prevnot = false; $where[] = sprintf('%s%s LIKE \'%%%s%%\'', $concat, $not, $gdo->escape($sql)); break; } break; case self::SEARCH_NEAR: echo "NEAR NOT SUPPORTED YET."; break; case self::SEARCH_BRACKET_OPEN: // if ($prev[0] === self::SEARCH_TERM) // { // $where[] = 'AND'; // } // $where[] = $sql; break; case self::SEARCH_BRACKET_CLOSE: break; case self::SEARCH_OR: case self::SEARCH_AND: $where[] = $sql; break; default: if ($token[0] === self::SEARCH_NOT) { $prevnot = true; $setprev = false; } break; } if ($setprev === true) { $prev = $token; } } $back = implode(' ', $where); return $back === '' ? '1' : $back; }
function warchall1createEMailB(WC_Challenge $chall, GDO_Database $db2, $eusername) { if (false === $db2->queryWrite("DELETE FROM gwf_audit_mails WHERE am_username='******'")) { return GWF_HTML::err('ERR_DATABASE', array(__FILE__, __LINE__)); } if ($db2->affectedRows() == 1) { return GWF_HTML::message('Warchall', $chall->lang('msg_nomails')); } $user = GWF_Session::getUser(); if ('' === ($email = $user->getValidMail())) { return GWF_HTML::error('Warchall', $chall->lang('err_no_mail')); } $eemail = GDO::escape($email); if (false === $db2->queryWrite("REPLACE INTO gwf_audit_mails VALUES('{$eusername}', '{$eemail}')")) { return GWF_HTML::err('ERR_DATABASE', array(__FILE__, __LINE__)); } return GWF_HTML::message('Warchall', $chall->lang('msg_mail')); }
public static function getDemoByMC($mc) { $mc = GDO::escape($mc); return self::table(__CLASS__)->selectFirstObject('*', "bmc_mc='{$mc}' AND bmc_options&2"); }
public function revertVote(GWF_VoteScoreRow $row, $ip, $userid) { // echo '<div>REVERT VOTE!</div>'; if (false === $this->countVote($row, -1)) { // echo GWF_HTML::err('ERR_GENERAL', array( __FILE__, __LINE__)); return false; } $vsid = $this->getID(); // $ip = (int) $ip; if ($ip === 0) { $userid = (int) $userid; return $row->deleteWhere("vsr_vsid={$vsid} AND vsr_uid={$userid}"); } else { $ip = GDO::escape($ip); return $row->deleteWhere("vsr_vsid={$vsid} AND vsr_ip='{$ip}'"); } }
private static function hashquote($hash, $quote = '"') { return $hash === null ? 'NULL' : $quote . GDO::escape($hash) . $quote; }
private function onLogin(IWebSocketConnection $user, $message) { $data = explode(' ', $message); if (count($data) !== 3) { return false; } $ename = GDO::escape($data[1]); $table = GDO::table('Dog_User'); if (false === ($dog_user = $table->selectFirstObject('*', "user_name='{$ename}'"))) { $this->sendToUser($user->getId(), 'XLIN2,Unknown username!'); return false; } if (false === GWF_Password::checkPasswordS($data[2], $dog_user->getVar('user_pass'))) { $this->sendToUser($user->getId(), 'XLIN3,Wrong password!'); return false; } $this->sendToUser($user->getId(), 'XLIN1'); $this->users[$user->getId()] = $dog_user; $this->addToQueue($user, $dog_user, 'PRIVMSG Dog :.login ' . $data[2]); return true; }
/** * Get a song by artist and title. * @param string $artist * @param string $title * @return Slay_Song */ public static function getByArtistTitle($artist, $title) { $title = GDO::escape($title); $artist = GDO::escape($artist); return self::table(__CLASS__)->selectFirstObject('*', "ss_title='{$title}' AND ss_artist='{$artist}'"); }
public static function hookRenameUser(GWF_User $user, $newname) { $newname = GDO::escape($newname); $oldname = $user->getEscaped('user_name'); return GDO::table(__CLASS__)->update("page_author_name='{$newname}'", "page_author_name='{$oldname}'"); }
public static function removeModuleVar(GWF_Module $module, $key) { $mid = $module->getID(); $ekey = GDO::escape($key); $var_t = GDO::table('GWF_ModuleVar'); return $var_t->deleteWhere("mv_mid={$mid} AND mv_key='{$ekey}'"); }
public static function getUsers($groupname, $orderby = 'user_name ASC') { $groupname = GDO::escape($groupname); return GDO::table('GWF_UserGroup')->selectAll('user.*', "group_name='{$groupname}'", $orderby, array('user', 'group'), -1, -1, GDO::ARRAY_A); }
/** * Get the times counterpart. * @return GWF_AuditLog */ public function getTimesLog() { $time = $this->getVar('al_time_start'); $rand = GDO::escape($this->getVar('al_rand')); return self::table(__CLASS__)->selectFirstObject('*', "al_time_start={$time} AND al_rand='{$rand}' AND al_type='time'"); }
private function onViewItems(SR_Clan $clan, SR_Player $player, $arg, $page) { $ipp = 10; $cid = $clan->getID(); $arg = GDO::escape($arg); $page = (int) $page; $table = GDO::table('SR_ClanBank'); $where = "sr4cb_cid={$cid} AND sr4cb_iname LIKE '%{$arg}%'"; $nItems = $table->countRows($where); if ($nItems === 0) { $player->msg('1007'); // $player->message('No match found.'); return true; } $nPages = GWF_PageMenu::getPagecount($ipp, $nItems); if ($page < 1 || $page > $nPages) { $player->msg('1009'); // $player->message('This page is empty.'); return false; } $from = GWF_PageMenu::getFrom($page, $ipp); if (false === ($result = $table->selectAll('sr4cb_iname, sr4cb_iamt', $where, 'sr4cb_iamt ASC, sr4cb_iname ASC', NULL, $ipp, $from, GDO::ARRAY_N))) { $player->message('DB ERROR 1.'); return false; } if (count($result) === 1) { return $this->onViewItem($clan, $player, $result[0][0], $result[0][1]); } $out = ''; $format = $player->lang('fmt_items'); foreach ($result as $row) { $from++; list($itemname, $amt) = $row; $damt = $amt === '1' ? '' : "({$amt})"; $out .= sprintf($format, $from, $itemname, $damt, $amt); // $out[] = sprintf('%d-%s%s', $from, $itemname, $amt); } $bot = Shadowrap::instance($player); return $bot->rply('5176', array($page, $nPages, substr($out, 2))); // return $bot->reply(sprintf('ClanBank page %d/%d: %s.', $page, $nPages, implode(', ', $out))); }
/** * Get a link by URL. * @param int $link_id * @return Dog_Link */ public static function getByURL($link_url) { $link_url = GDO::escape($link_url); return self::table(__CLASS__)->selectFirstObject('*', "link_url='{$link_url}'"); }