public static function exists($uid, $start = null, $end = null) { $uid = Db::convertType($uid); $dateQuery = Utils::dateQuery($start, $end); $inv_exist = self::first(['$or' => [["user_id" => $uid, "start" => ['$lte' => $dateQuery['start'], '$lte' => $dateQuery['end']], "end" => ['$gte' => $dateQuery['start'], '$gte' => $dateQuery['end']]], ["user_id" => $uid, "start" => Db::dateQuery($start, $end), "end" => ['$gte' => $dateQuery['start'], '$gte' => $dateQuery['end']]], ["user_id" => $uid, "start" => ['$lte' => $dateQuery['start'], '$lte' => $dateQuery['end']], "end" => Db::dateQuery($start, $end)], ["user_id" => $uid, "start" => Db::dateQuery($start, $end), "end" => Db::dateQuery($start, $end)]]]); return $inv_exist; }
public function inUse() { $count = Ad::count(['org_id' => $this->org_id, 'category' => ['$elemMatch' => ['$eq' => Utils::mongoObjectId($this->_id)]]]); if ($count === 0) { return false; } else { return true; } }
public function testDateQuery() { $start = date('Y-m-d', strtotime('-3 day')); $end = date('Y-m-d'); $dateQuery = Utils::dateQuery($start, $end); $startObj = $dateQuery['start']; $endObj = $dateQuery['end']; $sec = $startObj->toDateTime()->getTimestamp(); $this->assertEquals($start, date('Y-m-d', $sec), 'Start Date doesnot match'); $sec = $endObj->toDateTime()->getTimestamp(); $this->assertEquals($end, date('Y-m-d', $sec), 'End Date doesnot match'); }
public static function campImport($uid, $advert_id, $urls, $extra = []) { $uid = Utils::mongoObjectId($uid); $advert_id = Utils::mongoObjectId($advert_id); $data = ['prop' => 'campImport', 'propid' => $uid, 'value' => ['advert_id' => $advert_id, 'urls' => $urls]]; if (!empty($extra)) { $data['value']['campaign'] = $extra; } $meta = new self($data); $meta->save(); return $meta; }
public static function exists($oid, $opts = []) { $oid = Db::convertType($oid); $dateQuery = Utils::dateQuery($opts); $multiple = $opts['multiple'] ?? false; if ($multiple) { $query = "all"; } else { $query = "first"; } $inv_exist = self::$query(['$or' => [["org_id" => $oid, "start" => ['$lte' => $dateQuery['start'], '$lte' => $dateQuery['end']], "end" => ['$gte' => $dateQuery['start'], '$gte' => $dateQuery['end']]], ["org_id" => $oid, "start" => Db::dateQuery($start, $end), "end" => ['$gte' => $dateQuery['start'], '$gte' => $dateQuery['end']]], ["org_id" => $oid, "start" => ['$lte' => $dateQuery['start'], '$lte' => $dateQuery['end']], "end" => Db::dateQuery($start, $end)], ["org_id" => $oid, "start" => Db::dateQuery($start, $end), "end" => Db::dateQuery($start, $end)]]]); return $inv_exist; }
public static function rssFeeds($org) { $users = \User::all(['org_id' => $org->_id, 'type' => 'advertiser'], ['_id']); $in = []; $result = []; foreach ($users as $u) { $in[] = $u->_id; } $platforms = \Platform::all(['user_id' => ['$in' => $in]], ['_id', 'url', 'user_id', 'meta']); foreach ($platforms as $p) { if (isset($p->meta['rss'])) { $result[Utils::getMongoID($p->_id)] = $p; } } return $result; }
protected static function _getStats($records, &$stats, $date) { $keys = ['country', 'os', 'device', 'referer']; foreach ($records as $r) { $obj = Utils::toArray($r); $arr =& $stats[$date]['meta']; foreach ($keys as $k) { if (!isset($arr[$k])) { $arr[$k] = []; } $index = $r['_id'][$k] ?? null; if (is_null($index)) { continue; } if (strlen(trim($index)) === 0) { $index = "Empty"; } ArrayMethods::counter($arr[$k], $index, $obj['count']); } } }
public static function sendMail(\Organization $org, $opts = []) { $mail = new PHPMailer(); // $mail->SMTPDebug = 3; // Enable verbose debug output $smtpConf = Meta::first(['prop' => 'orgSmtp', 'propid' => $org->_id]); if (!$smtpConf) { // use the Mailgun API to send mail $opts['org'] = $org; Mail::send($opts); return; } $smtpConf = $smtpConf->value; $password = Utils::decrypt($smtpConf['password'], $org->_id); $mail->isSMTP(); $mail->Host = $smtpConf['server']; // Specify main and backup SMTP servers $mail->SMTPAuth = true; // Enable SMTP authentication $mail->Username = $smtpConf['username']; // SMTP username $mail->Password = $password; // SMTP password $mail->SMTPSecure = 'tls'; // Enable TLS encryption, `ssl` also accepted $mail->Port = 587; // TCP port to connect to $mail->setFrom($smtpConf['email'], $smtpConf['from']); foreach ($opts['to'] as $email) { $mail->addAddress($email); } $mail->isHTML(true); $mail->Subject = $opts['subject']; $mail->Body = Mail::_body($opts); if (!$mail->send()) { throw new \Exception('Failed to send email: ' . $mail->ErrorInfo); } else { return true; } }
public static function overall($dateQuery = [], $user = null) { $q = []; $clicks = []; $conversions = []; $impressions = []; $payouts = []; $total_clicks = 0; $total_conversions = 0; $total_payouts = 0; $total_impressions = 0; if (is_array($user)) { $in = ArrayMethods::arrayKeys($user, '_id'); $q["user_id"] = ['$in' => $in]; } elseif ($user) { $q["user_id"] = $user->id; } if (count($dateQuery) > 0) { $q["created"] = ['$gte' => $dateQuery['start'], '$lte' => $dateQuery['end']]; } $performances = self::all($q, ['revenue', 'clicks', 'created', 'impressions', 'conversions']); foreach ($performances as $p) { //calculating datewise $date = $p->created->format('Y-m-d'); $total_clicks += $p->clicks; ArrayMethods::counter($clicks, $date, $p->clicks); $total_conversions += $p->conversions; ArrayMethods::counter($conversions, $date, $p->conversions); $total_impressions += $p->impressions; ArrayMethods::counter($impressions, $date, $p->impressions); $total_payouts += $p->revenue; ArrayMethods::counter($payouts, $date, $p->revenue); } ksort($clicks); ksort($impressions); ksort($payouts); $clicks = Utils::dateArray($clicks); $impressions = Utils::dateArray($impressions); $payouts = Utils::dateArray($payouts); return ["impressions" => $impressions, "total_impressions" => $total_impressions, "clicks" => $clicks, "total_clicks" => $total_clicks, "conversions" => $conversions, "total_conversions" => $total_conversions, "payouts" => $payouts, "total_payouts" => $total_payouts]; }
public static function find(&$search, $key, $fields = []) { $key = Utils::getMongoID($key); if (!array_key_exists($key, $search)) { $ad = self::first(['_id' => $key], $fields); $search[$key] = $ad; } else { $ad = $search[$key]; } return $ad; }
/** * Converts the MongoDB result to an object of class * whose parent is \Shared\Model */ protected function _convert($record) { if (!$record) { return null; } $columns = $this->getColumns(); $record = (array) $record; $class = get_class($this); $c = new $class(); foreach ($record as $key => $value) { if (!property_exists($this, "_{$key}")) { continue; } $raw = "_{$key}"; if (is_object($value)) { if (Db::isType($value, 'id')) { $c->{$raw} = $this->getMongoID($value); } else { if (Db::isType($value, 'date')) { $v = $value->toDateTime(); $v->settimezone(new \DateTimeZone('Asia/Kolkata')); $c->{$raw} = $v; } else { if (Db::isType($value, 'document')) { $c->{$raw} = Utils::toArray($value); } else { // fallback case $c->{$raw} = (object) $value; } } } } else { $c->{$raw} = $value; } } return $c; }
public static function dateQuery($start = null, $end = null) { $changed = false; if ($start && $end) { if (self::isType($start, 'date') && self::isType($end, 'date')) { $dq = ['start' => $start, 'end' => $end]; $changed = true; } } if (!$changed) { $dq = \Shared\Utils::dateQuery(['start' => $start, 'end' => $end]); } $result = []; if ($start) { $result['$gte'] = $dq['start']; } if ($end) { $result['$lte'] = $dq['end']; } return $result; }
public function removeFields() { $meta = $this->_meta; $afields = $meta['afields'] ?? []; foreach ($meta['afields'] as $key => $value) { Utils::media($value, 'remove'); } }
/** * Finds the commission based on the "ad_id" * @param array &$search Array of Commission (to prevent querying from database again and again) * @param mixed $key Object|String representing Ad ID */ public static function find(&$search, $key) { $key = \Shared\Utils::getMongoID($key); if (!array_key_exists($key, $search)) { $commissions = self::all(['ad_id' => $key], ['rate', 'revenue', 'model', 'coverage']); $search[$key] = $comm = self::filter($commissions); } else { $comm = $search[$key]; } return $comm; }
/** * @before _secure * @after _displayData */ public function platforms($id = null) { $this->seo(["title" => "Platform wise click stats"]); $view = $this->getActionView(); $org = $this->org; $clickCol = Registry::get("MongoDB")->clicks; // find the platforms $platforms = \Platform::all(['user_id' => ['$in' => $org->users('advertisers')]], ['_id', 'url']); if (count($platforms) === 0) { return $view->set(['platforms' => [], 'publishers' => []]); } $key = array_rand($platforms); $url = RM::get('link', $platforms[$key]->url); // find ads having this url $ads = \Ad::all(['org_id' => $org->_id], ['_id', 'url']); $in = Utils::mongoObjectId(array_keys($ads)); $matched = []; foreach ($ads as $a) { $regex = preg_quote($url, '.'); if (preg_match('#^' . $regex . '#', $a->url)) { $matched[] = Utils::mongoObjectId($a->_id); } } if (count($matched) === 0) { $query['adid'] = ['$in' => $in]; } else { $query['adid'] = ['$in' => $matched]; } $query['is_bot'] = false; $query['created'] = Db::dateQuery($this->start, $this->end); $records = $clickCol->aggregate([['$match' => $query], ['$projection' => ['_id' => 1, 'pid' => 1]], ['$group' => ['_id' => '$pid', 'count' => ['$sum' => 1]]], ['$sort' => ['count' => -1]]]); $result = []; $publishers = []; foreach ($records as $r) { $obj = (object) $r; $id = Utils::getMongoID($obj->_id); $user = User::first(['_id' => $id], ['_id', 'name']); $result[$id] = (object) ['_id' => $user->_id, 'name' => $user->name, 'clicks' => $obj->count]; } $view->set(['platforms' => $platforms, 'link' => $url, 'publishers' => $result]); }
/** * @before _secure */ public function import() { $this->seo(['title' => 'Campaign Import', 'description' => 'Create a new campaign']); $view = $this->getActionView(); $org = $this->org; $advertisers = \User::all(["org_id = ?" => $this->org->_id, 'type = ?' => 'advertiser'], ['_id', 'name']); if (count($advertisers) === 0) { $this->redirect('/advertiser/add.html'); } $platforms = \Platform::rssFeeds($this->org); $view->set('advertiser', $advertisers); $action = RM::post('action', ''); switch ($action) { case 'campImport': $this->_import($org, $advertisers, $view); break; case 'platform': $pid = RM::post('pid'); $p = $platforms[$pid]; $meta = $p->meta; $meta['rss']['url'] = RM::post('url'); $parsing = (bool) (int) RM::post('parsing', "1"); $meta['rss']['parsing'] = $parsing; $p->meta = $meta; $p->save(); $view->set('message', 'Updated Rss feed'); break; case 'newRss': $url = RM::post('rss_link'); $a = array_values($advertisers)[0]; $advert_id = RM::post('advert_id', $a->getMongoID()); $advert = \User::first(['_id = ?' => $advert_id, 'type = ?' => 'advertiser']); if (!$advert) { return $view->set('message', 'Invalid Request!!'); } // try to find a platform for the given advertiser $domain = parse_url($url, PHP_URL_HOST); $regex = preg_quote($domain); $p = \Platform::first(['user_id' => $advert_id, 'url' => Utils::mongoRegex($regex)]); $msg = "RSS Feed Added. Campaigns Will be imported within an hour"; try { // Now schedule importing of campaigns $result = \Shared\Rss::getFeed($url); $rate = RM::post('rate', 0.2); $revenue = RM::post('revenue', 0.25); $rss = ['url' => $url, 'parsing' => true, 'lastCrawled' => $result['lastCrawled'], 'campaign' => ['model' => RM::post('model', 'cpc'), 'rate' => $this->currency($rate), 'revenue' => $this->currency($rate)]]; // if platform not found then add new if (!$p) { $p = new \Platform(['url' => $domain, 'user_id' => $advert_id]); } $meta = $p->meta; $meta['rss'] = $rss; $p->meta = $meta; $p->save(); \Meta::campImport($this->user->_id, $advert_id, $result['urls'], $rss['campaign']); } catch (\Exception $e) { $msg = "Internal Server Error!!"; } $view->set('message', $msg); break; } $platforms = \Platform::rssFeeds($this->org); $view->set('platforms', $platforms); }
/** * @before _secure */ public function create() { $this->_create(); $view = $this->getActionView(); if (RM::type() == 'POST') { $img = null; // give preference to uploaded image $img = $this->_upload('image', 'images', ['extension' => 'jpe?g|gif|bmp|png|tif']); if (!$img) { $img_url = RM::post("image_url"); $img = Shared\Utils::downloadImage($img_url); } if (!$img) { return $view->set('message', 'Failed to upload the image'); } $expiry = RM::post('expiry'); $campaign = new \Ad(['user_id' => RM::post('advert_id'), 'title' => RM::post('title'), 'description' => RM::post('description'), 'org_id' => $this->org->_id, 'url' => RM::post('url'), 'preview_url' => RM::post('preview_url'), 'category' => \Ad::setCategories(RM::post('category')), 'image' => $img, 'type' => RM::post('type', 'article'), 'device' => RM::post('device', ['all']), 'live' => false]); $visibility = RM::post('visibility', 'public'); if ($visibility === "private") { $campaign->meta = ['private' => true]; } $permission = RM::post('permission', false); if ($permission == "yes") { $campaign->meta = ['permission' => true]; } if ($expiry) { $campaign->expiry = $expiry; } try { if ($campaign->type === "video") { $url = RM::post('videoUrl'); $ytdl = new Downloader($url); $campaign->getMeta()['processing'] = true; $campaign->getMeta()['videoUrl'] = $ytdl->getUrl(); } } catch (\Exception $e) { // Invalid URL return $view->set("errors", ['videoUrl' => ["Pass a valid youtube video URL"]]); } if (!$campaign->validate()) { return $view->set("errors", $campaign->errors); } $campaign->save(); $models = RM::post('model'); $comm_desc = RM::post('comm_desc'); $revenue = RM::post('revenue'); $rate = RM::post('rate'); $coverage = RM::post('coverage'); foreach ($models as $key => $value) { $commission = new \Commission(['ad_id' => $campaign->_id, 'description' => $comm_desc[$key], 'model' => $value, 'rate' => $this->currency($rate[$key]), 'revenue' => $this->currency($revenue[$key]), 'coverage' => $coverage[$key]]); $commission->save(); } Registry::get("session")->set('$flashMessage', 'Campaign Created successfully!!'); $this->redirect("/campaign/manage.html"); } }
/** * @before _secure * @after _cleanUp */ public function campaign($id = null) { $view = $this->getActionView(); $org = $this->_org; $active = RequestMethods::get('active', 1); $fields = ['_id', 'title', 'description', 'image', 'url', 'device', 'expiry', 'created']; $commFields = ['model', 'rate', 'revenue', 'coverage']; if ($id) { $campaign = Ad::first(['_id' => $id, 'org_id' => $org->_id], $fields); } else { $campaign = null; } if ($id && !$campaign) { return $this->failure('30'); } $type = RequestMethods::type(); switch ($type) { case 'GET': if (!$id) { // display list of campaigns $ads = Ad::all(['org_id' => $org->_id, 'live' => $active], $fields); $ads = Ad::objectArr($ads, $fields); $results = []; foreach ($ads as $id => $a) { $arr = Utils::toArray($a); $comms = Commission::all(['ad_id' => $a->_id], $commFields); $arr['commissions'] = Ad::objectArr($comms, $commFields); $results[$id] = (object) $arr; } $data = ['campaigns' => $results]; $view->set('data', $data); } else { $ads = Ad::objectArr($campaign, $fields); $campaign = array_shift($ads); $comm = Commission::all(['ad_id' => $campaign->_id], $commFields); $data = ['campaign' => $campaign, 'commissions' => Commission::objectArr($comm, $commFields)]; $view->set('data', $data); } break; case 'POST': if ($id) { // edit a particular campaign } else { // create a new campaign $fields = ['title', 'description', 'url', 'expiry', 'category', 'device', 'user_id']; $img = RequestMethods::post('image'); // contains image url $campaign = new Ad(['org_id' => $org->_id, 'type' => 'article', 'image' => Utils::media($img, 'download')]); foreach ($fields as $f) { $campaign->{$f} = RequestMethods::post($f); } $view->set('success', false); $visibility = RequestMethods::post('visibility', 'public'); if ($visibility === 'private') { $campaign->getMeta()['private'] = true; } $opts = ['devices' => array_keys(Shared\Markup::devices()), 'advertisers' => $org->users('advertiser', false)]; if (true) { // $campaign->save(); $arr = ArrayMethods::reArray($_POST['commissions']); var_dump($arr); var_dump($_POST['commissions']); $view->set('success', true); } else { $data = ['errors' => $campaign->errors]; $view->set('data', $data); } } break; case 'DELETE': $message = $campaign->delete(); $view->set($message); break; } }
public function users($type = "publisher", $object = true) { $users = \User::all(["org_id = ?" => $this->_id, "type = ?" => $type], ["_id"]); $ids = array_keys($users); if ($object === true) { return Utils::mongoObjectId($ids); } else { if ($object === 'users') { return $users; } else { if ($object === false) { return $ids; } } } }
public static function classify($clicks, $type = 'adid') { $classify = []; foreach ($clicks as $result) { $c = ArrayMethods::toObject($result); $key = Utils::getMongoID($c->{$type} ?? ''); if (strlen($key) == 0) { $key = "Empty"; } $key = str_replace(".", "-", $key); if (!isset($classify[$key]) || !array_key_exists($key, $classify)) { $classify[$key] = []; } $classify[$key][] = $c; } return $classify; }
/** * @before _secure */ public function platforms($id = null) { $this->seo(array("title" => "Platforms")); $view = $this->getActionView(); $query['user_id'] = ['$in' => $this->org->users('publisher')]; $limit = RM::get("limit", 20); $page = RM::get("page", 1); $property = RM::get("property", ''); $value = RM::get("value"); if (in_array($property, ["live", "user_id"])) { $query["{$property} = ?"] = $value; } else { if (in_array($property, ["url"])) { $query[$property] = Utils::mongoRegex($value); } } if (RM::type() === 'POST') { $p = \Platform::first(['_id' => $id, 'user_id' => $query['user_id']]); if (!$p) { return $view->set('message', "Invalid Request!!"); } try { $updateAble = ['live', 'user_id', 'url']; foreach ($_POST as $key => $value) { if (in_array($key, $updateAble)) { $p->{$key} = $value; } } $p->save(); return $view->set('message', 'Platform updated!!'); } catch (\Exception $e) { return $view->set('message', "Invalid Request Parameters!!"); } } if (RM::type() === 'DELETE') { $p = \Platform::first(['_id' => $id, 'user_id' => $query['user_id']]); if (!$p) { return $view->set('message', "Invalid Request!!"); } $p->delete(); return $view->set('message', "Platform Removed!!"); } $platforms = Platform::all($query, [], 'created', 'desc', $limit, $page); $count = Platform::count($query); $view->set("platforms", $platforms)->set("count", $count)->set("property", $property)->set("value", $value)->set("limit", $limit)->set("page", $page); }
public static function customFields($user, $org) { $afields = \Meta::search('customField', $org); if (count($afields) > 0) { $meta = $user->meta ?? []; $extraFields = []; foreach ($afields as $value) { $key = $value['name']; $type = $value['type']; $message = $value['label'] . " is required!!"; switch ($type) { case 'file': $v = Utils::media($key, 'upload', ['extension' => 'jpe?g|gif|bmp|png|tif|pdf']); if (!$v) { $message = "Please Upload a valid image or pdf file"; } break; case 'text': $v = RequestMethods::post($key); break; case 'date': $d = RequestMethods::post($key, date('Y-m-d')); $v = Db::convertType($d, 'date'); break; default: $v = ''; break; } if (!$v && $value['required']) { return ["message" => $message, "success" => false]; } $extraFields[$key] = $v; } $meta['afields'] = $extraFields; $user->meta = $meta; } $user->save(); return ["success" => true]; }
public function generateBills() { $orgs = Organization::all(["live = ?" => true]); foreach ($orgs as $org) { $imp_cost = 0; $click_cost = 0; $month_ini = new DateTime("first day of last month"); $month_end = new DateTime("last day of last month"); $start = $month_ini->format('Y-m-d'); $end = $month_end->format('Y-m-d'); $dateQuery = Utils::dateQuery(['start' => $start, 'end' => $end]); // find advertiser performances to get clicks and impressions $performances = \Performance::overall($dateQuery, User::all(['org_id' => $org->_id, 'type' => 'advertiser'], ['_id'])); $clicks = $performances['total_clicks']; if ($clicks > 1000) { $click_cost = 0.001 * $clicks * $org->meta["bill"]["tcc"]; } $impressions = $performances['total_impressions']; if ($impressions > 100000) { $imp_cost = 0.001 * 0.001 * $impressions * $org->meta["bill"]["mic"]; } $total = $click_cost + $imp_cost; $bill = new Bill(["org_id" => $org->id, "impressions" => $impressions, "clicks" => $clicks, "mic" => $org->meta["bill"]["mic"], "tcc" => $org->meta["bill"]["tcc"], "start" => $start, "end" => $end, "amount" => $total, "live" => false, "created" => Db::time('-1 day')]); if ($total > 1) { $bill->save(); $user = User::first(["org_id = ?" => $org->id, "type = ?" => "admin"]); Mail::send(['user' => $user, 'bill' => $bill, 'template' => 'adminBilling', 'subject' => 'Billing at vNative', 'click_cost' => $click_cost, 'imp_cost' => $imp_cost, 'org' => $org]); } } }