Beispiel #1
0
 /**
  * Send the notification
  */
 public function send()
 {
     $Client = new Client();
     $failures = array();
     $result = array();
     $data = ["registration_ids" => [], "data" => ["title" => $this->data['subject'], "message" => $this->data['body']]];
     foreach ($this->data['recipients'] as $user_id => $userdata) {
         $ThisUser = UserFactory::CreateUser($user_id);
         $subscriptions = Notifications::getPushSubscriptions($ThisUser);
         foreach ($subscriptions as $sub) {
             $data['registration_ids'][] = $sub['registration_id'];
         }
     }
     if (empty($data['registration_ids'])) {
         return;
     }
     try {
         $response = $Client->post($sub['endpoint'], ["headers" => ["Content-Type" => "application/json", "Authorization" => "key=" . GOOGLE_SERVER_KEY], "json" => $data]);
         $body = $response->getBody();
         $result = json_decode($body, true);
         $this->removeStaleSubscriptions($result, $data['registration_ids']);
         $return = array("stat" => true, "failures" => $result);
     } catch (RequestException $e) {
         $return = ["stat" => false, "failures" => ["message" => $e->getMessage(), "body" => $e->getRequest()->getBody()]];
     }
     return $return;
 }
Beispiel #2
0
 /**
  * Update the author for a specific image
  * @since Version 3.10.0
  * @param \Railpage\Images\Image $imageObject
  * @return \Railpage\Images\Image
  */
 public static function updateAuthor(Image $imageObject)
 {
     if ($id = UserUtility::findFromFlickrNSID($imageObject->author->id)) {
         $imageObject->author->railpage_id = $id;
         $imageObject->author->User = UserFactory::CreateUser($imageObject->author->railpage_id);
         $imageObject->commit();
     }
     return $imageObject;
 }
Beispiel #3
0
 /**
  * Populate this object
  * @since Version 3.9.1
  * @return void
  */
 private function populate()
 {
     $query = "SELECT * FROM location_corrections WHERE id = ?";
     if (!($row = $this->db->fetchRow($query, $this->id))) {
         return;
     }
     $this->comments = $row['comments'];
     $this->DateAdded = new DateTime($row['date_added']);
     $this->Location = new Location($row['location_id']);
     $this->setAuthor(UserFactory::CreateUser($row['user_id']));
     if (!is_null($row['date_closed'])) {
         $this->DateClosed = new DateTime($row['date_closed']);
     }
     return;
 }
Beispiel #4
0
 /**
  * Get the next photo competition
  * @since Version 3.10.0
  * @param \Railpage\Gallery\Competition $photoComp
  * @return \Railpage\Gallery\Competition
  */
 public function getNextCompetition(Competition $photoComp)
 {
     $query = "SELECT id \r\n            FROM image_competition\r\n            WHERE submissions_date_close >= NOW()\r\n            AND id != ?\r\n            ORDER BY submissions_date_open ASC\r\n            LIMIT 0, 1";
     $params = [$photoComp->id];
     $id = $this->db->fetchOne($query, $params);
     try {
         $photoComp = new Competition($id);
     } catch (Exception $e) {
         // throw it away
     }
     if ($photoComp instanceof Competition && filter_var($photoComp->id, FILTER_VALIDATE_INT)) {
         return $photoComp;
     }
     $NextComp = $this->autoPopulateNextComp();
     $NextComp->setAuthor(UserFactory::CreateUser(User::SYSTEM_USER_ID))->commit();
     return $NextComp;
 }
Beispiel #5
0
 /**
  * Populate this image with fresh data
  *
  * @since Version 3.8.7
  * @return $this
  *
  * @param boolean $force
  * @param int     $option
  *
  * @throws \Exception if the photo cannot be found on the image provider
  * @todo  Split this into utility functions
  */
 public function populate($force = false, $option = null)
 {
     if ($force === false && !$this->isStale()) {
         return $this;
     }
     Debug::LogCLI("Fetching data from " . $this->provider . " for image ID " . $this->id . " (photo ID " . $this->photo_id . ")");
     /**
      * Start the debug timer
      */
     if (RP_DEBUG) {
         global $site_debug;
         $debug_timer_start = microtime(true);
     }
     /**
      * New and improved populator using image providers
      */
     $Provider = $this->getProvider();
     $data = false;
     try {
         $data = $Provider->getImage($this->photo_id, $force);
     } catch (Exception $e) {
         $expected = array(sprintf("Unable to fetch data from Flickr: Photo \"%s\" not found (invalid ID) (1)", $this->photo_id), "Unable to fetch data from Flickr: Photo not found (1)");
         if (in_array($e->getMessage(), $expected)) {
             $where = ["image_id = ?" => $this->id];
             $this->db->delete("image_link", $where);
             $where = ["id = ?" => $this->id];
             $this->db->delete("image", $where);
             throw new Exception("Photo no longer available from " . $this->provider);
         }
     }
     if ($data) {
         $this->sizes = $data['sizes'];
         $this->title = empty($data['title']) ? "Untitled" : $data['title'];
         $this->description = $data['description'];
         $this->meta = array("dates" => array("posted" => $data['dates']['uploaded'] instanceof DateTime ? $data['dates']['uploaded']->format("Y-m-d H:i:s") : $data['dates']['uploaded']['date'], "taken" => $data['dates']['taken'] instanceof DateTime ? $data['dates']['taken']->format("Y-m-d H:i:s") : $data['dates']['taken']['date']));
         $this->author = new stdClass();
         $this->author->username = $data['author']['username'];
         $this->author->realname = !empty($data['author']['realname']) ? $data['author']['realname'] : $data['author']['username'];
         $this->author->id = $data['author']['id'];
         $this->author->url = "https://www.flickr.com/photos/" . $this->author->id;
         if ($user_id = UserUtility::findFromFlickrNSID($this->author->id)) {
             $data['author']['railpage_id'] = $user_id;
         }
         if (isset($data['author']['railpage_id']) && filter_var($data['author']['railpage_id'], FILTER_VALIDATE_INT)) {
             $this->author->User = UserFactory::CreateUser($data['author']['railpage_id']);
         }
         /**
          * Load the tags
          */
         if (isset($data['tags']) && is_array($data['tags']) && count($data['tags'])) {
             foreach ($data['tags'] as $row) {
                 $this->meta['tags'][] = $row['raw'];
             }
         }
         /**
          * Load the Place object
          */
         if ($option != Images::OPT_NOPLACE && isset($data['location']) && !empty($data['location'])) {
             try {
                 $this->Place = Place::Factory($data['location']['latitude'], $data['location']['longitude']);
             } catch (Exception $e) {
                 // Throw it away. Don't care.
             }
         }
         $this->links = new stdClass();
         $this->links->provider = isset($data['urls']['url'][0]['_content']) ? $data['urls']['url'][0]['_content'] : $data['urls'][key($data['urls'])];
         $this->commit();
         $this->cacheGeoData();
         return true;
     }
     /**
      * Fetch data in various ways for different photo providers
      */
     switch ($this->provider) {
         /**
          * Picasa
          */
         case "picasaweb":
             if (empty($this->meta) && !is_null(filter_input(INPUT_SERVER, "HTTP_REFERER", FILTER_SANITIZE_URL)) && strpos(filter_input(INPUT_SERVER, "HTTP_REFERER", FILTER_SANITIZE_URL), "picasaweb.google.com")) {
                 $album = preg_replace("@(http|https)://picasaweb.google.com/([a-zA-Z\\-\\.]+)/(.+)@", "\$2", filter_input(INPUT_SERVER, "HTTP_REFERER", FILTER_SANITIZE_URL));
                 if (is_string($album)) {
                     $update_url = sprintf("https://picasaweb.google.com/data/feed/api/user/%s/photoid/%s?alt=json", $album, $this->photo_id);
                 }
             }
             if (isset($update_url)) {
                 $data = file_get_contents($update_url);
                 $json = json_decode($data, true);
                 $this->meta = array("title" => $json['feed']['subtitle']['$t'], "description" => $json['feed']['title']['$t'], "dates" => array("posted" => date("Y-m-d H:i:s", $json['feed']['gphoto$timestamp']['$t'])), "sizes" => array("original" => array("width" => $json['feed']['gphoto$width']['$t'], "height" => $json['feed']['gphoto$height']['$t'], "source" => str_replace(sprintf("/s%d/", $json['feed']['media$group']['media$thumbnail'][0]['width']), sprintf("/s%d/", $json['feed']['gphoto$width']['$t']), $json['feed']['media$group']['media$thumbnail'][0]['url'])), "largest" => array("width" => $json['feed']['gphoto$width']['$t'], "height" => $json['feed']['gphoto$height']['$t'], "source" => str_replace(sprintf("/s%d/", $json['feed']['media$group']['media$thumbnail'][0]['width']), sprintf("/s%d/", $json['feed']['gphoto$width']['$t']), $json['feed']['media$group']['media$thumbnail'][0]['url']))), "photo_id" => $json['feed']['gphoto$id']['$t'], "album_id" => $json['feed']['gphoto$albumid']['$t'], "updateurl" => sprintf("%s?alt=json", $json['feed']['id']['$t']));
                 foreach ($json['feed']['media$group']['media$thumbnail'] as $size) {
                     if ($size['width'] <= 500 && $size['width'] > 200) {
                         $this->meta['sizes']['small'] = array("width" => $size['width'], "height" => $size['height'], "source" => $size['url']);
                     }
                     if ($size['width'] <= 200) {
                         $this->meta['sizes']['small'] = array("width" => $size['width'], "height" => $size['height'], "source" => $size['url']);
                     }
                     if ($size['width'] <= 1024 && $size['width'] > 500) {
                         $this->meta['sizes']['large'] = array("width" => $size['width'], "height" => $size['height'], "source" => $size['url']);
                     }
                 }
                 foreach ($json['feed']['link'] as $link) {
                     if ($link['rel'] == "alternate" && $link['type'] == "text/html") {
                         $this->meta['source'] = $link['href'];
                     }
                 }
                 if ($option != Images::OPT_NOPLACE && isset($json['feed']['georss$where']['gml$Point']) && is_array($json['feed']['georss$where']['gml$Point'])) {
                     $pos = explode(" ", $json['feed']['georss$where']['gml$Point']['gml$pos']['$t']);
                     $this->Place = Place::Factory($pos[0], $pos[1]);
                 }
                 $this->title = $this->meta['title'];
                 $this->description = $this->meta['description'];
                 $this->author = new stdClass();
                 $this->author->username = $album;
                 $this->author->id = $album;
                 $this->author->url = sprintf("%s/%s", $json['feed']['generator']['uri'], $album);
             }
             $this->sizes = $this->meta['sizes'];
             $this->commit();
             break;
             /**
              * Vicsig
              */
         /**
          * Vicsig
          */
         case "vicsig":
             if (strpos(filter_input(INPUT_SERVER, "HTTP_REFERER", FILTER_SANITIZE_URL), "vicsig.net/photo")) {
                 $this->meta['source'] = filter_input(INPUT_SERVER, "HTTP_REFERER", FILTER_SANITIZE_STRING);
                 $response = $this->GuzzleClient->get($this->meta['source']);
                 if ($response->getStatusCode() != 200) {
                     throw new Exception(sprintf("Failed to fetch image data from %s: HTTP error %s", $this->provider, $response->getStatusCode()));
                 }
                 /**
                  * Start fetching it
                  */
                 $data = $response->getBody();
                 $doc = new DomDocument();
                 $doc->loadHTML($data);
                 $images = $doc->getElementsByTagName("img");
                 foreach ($images as $element) {
                     if (!empty($element->getAttribute("src")) && !empty($element->getAttribute("alt"))) {
                         #$image_title = $element->getAttribute("alt");
                         $this->sizes['original'] = array("source" => $element->getAttribute("src"), "width" => $element->getAttribute("width"), "height" => $element->getAttribute("height"));
                         if (substr($this->sizes['original']['source'], 0, 1) == "/") {
                             $this->sizes['original']['source'] = "http://www.vicsig.net" . $this->sizes['original']['source'];
                         }
                         break;
                     }
                 }
                 $desc = $doc->getElementsByTagName("i");
                 foreach ($desc as $element) {
                     if (!isset($image_desc)) {
                         $text = trim($element->nodeValue);
                         $text = str_replace("\r\n", "\n", $text);
                         $text = explode("\n", $text);
                         /**
                          * Loop through the exploded text and remove the obvious date/author/etc
                          */
                         foreach ($text as $k => $line) {
                             // Get the author
                             if (preg_match("@Photo: @i", $line)) {
                                 $this->author = new stdClass();
                                 $this->author->realname = str_replace("Photo: ", "", $line);
                                 $this->author->url = filter_input(INPUT_SERVER, "HTTP_REFERER", FILTER_SANITIZE_STRING);
                                 unset($text[$k]);
                             }
                             // Get the date
                             try {
                                 $this->meta['dates']['posted'] = (new DateTime($line))->format("Y-m-d H:i:s");
                                 unset($text[$k]);
                             } catch (Exception $e) {
                                 // Throw it away
                             }
                         }
                         /**
                          * Whatever's left must be the photo title and description
                          */
                         foreach ($text as $k => $line) {
                             if (empty($this->title)) {
                                 $this->title = $line;
                                 continue;
                             }
                             $this->description .= $line;
                         }
                         $this->links = new stdClass();
                         $this->links->provider = filter_input(INPUT_SERVER, "HTTP_REFERER", FILTER_SANITIZE_STRING);
                         $this->commit();
                     }
                 }
             }
             break;
     }
     /**
      * End the debug timer
      */
     if (RP_DEBUG) {
         $site_debug[] = __CLASS__ . "::" . __FUNCTION__ . "() : completed in " . round(microtime(true) - $debug_timer_start, 5) . "s";
     }
     return $this;
 }
Beispiel #6
0
 /** 
  * Fetch the message
  * @since Version 3.3
  * @version 3.3
  * @return boolean
  */
 public function fetch()
 {
     if (!filter_var($this->id, FILTER_VALIDATE_INT)) {
         throw new Exception("Cannot fetch PM - no message ID provided");
     }
     $this->mckey = "railpage:messsages.message_id=" . $this->id;
     if (!($row = $this->Memcached->fetch($this->mckey))) {
         $query = "SELECT pm.*, pmt.*, ufrom.user_id AS user_id_from, ufrom.username AS username_from, ufrom.user_avatar AS from_user_avatar, ufrom.user_allow_viewonline AS from_user_viewonline, uto.user_id AS user_id_to, uto.username AS username_to, uto.user_allow_viewonline AS to_user_viewonline\r\n                        FROM nuke_bbprivmsgs AS pm\r\n                        LEFT JOIN nuke_bbprivmsgs_text AS pmt ON pm.privmsgs_id = pmt.privmsgs_text_id\r\n                        LEFT JOIN nuke_users AS ufrom ON pm.privmsgs_from_userid = ufrom.user_id\r\n                        LEFT JOIN nuke_users AS uto ON pm.privmsgs_to_userid = uto.user_id\r\n                        WHERE pm.privmsgs_id = ?";
         $row = $this->db->fetchRow($query, $this->id);
         $this->Memcached->save($this->mckey, $row);
     }
     if (!isset($row) || count($row) == 0) {
         return;
     }
     // Nasty way of doing it, but it should work for now.
     // Remember to extend BOTH open AND close when adding another bbcode to match
     //$bbcode_preg_open   = "@\[(img|url|list|b|i|u)\:([a-zA-Z0-9]+)\]@";
     //$bbcode_preg_close  = "@\[/(img|url|list|b|i|u)\:([a-zA-Z0-9]+)\]@";
     $this->id = $row['privmsgs_id'];
     $this->date = $row['privmsgs_date'];
     $this->subject = $row['privmsgs_subject'];
     $this->body = trim($row['privmsgs_text']);
     $this->bbcode_uid = $row['privmsgs_bbcode_uid'];
     $this->type = $row['privmsgs_type'];
     $this->enable_bbcode = $row['privmsgs_enable_bbcode'];
     $this->enable_html = $row['privmsgs_enable_html'];
     $this->enable_smilies = $row['privmsgs_enable_smilies'];
     $this->enable_signature = $row['privmsgs_attach_sig'];
     $this->object_id = $row['object_id'];
     $this->hide_from = $row['hide_from'];
     $this->hide_to = $row['hide_to'];
     $this->setRecipient(UserFactory::CreateUser($row['privmsgs_to_userid']));
     $this->setAuthor(UserFactory::CreateUser($row['privmsgs_from_userid']));
 }
Beispiel #7
0
 /**
  * Constructor
  * @since Version 3.8.7
  * @param int $id
  */
 public function __construct($id = NULL)
 {
     parent::__construct();
     $this->Module = new Module("events");
     $this->namespace = $this->Module->namespace;
     if (!filter_var($id, FILTER_VALIDATE_INT)) {
         return;
     }
     if (!($row = $this->db->fetchRow("SELECT * FROM event_dates WHERE id = ?", $id))) {
         return;
     }
     $this->id = $id;
     $this->Event = Factory::CreateEvent($row['event_id']);
     $this->Date = new DateTime($row['date']);
     $this->meta = json_decode($row['meta'], true);
     $this->status = $row['status'];
     $this->url = new Url("/events?mode=event.date&event_id=" . $this->Event->id . "&date_id=" . $this->id);
     $this->url->approve = sprintf("/events?mode=event.date.setstatus&date_id=%d&status=%d", $this->id, self::STATUS_RUNNING);
     $this->url->reject = sprintf("/events?mode=event.date.setstatus&date_id=%d&status=%d", $this->id, self::STATUS_REJECTED);
     $this->url->cancel = sprintf("/events?mode=event.date.setstatus&date_id=%d&status=%d", $this->id, self::STATUS_CANCELLED);
     $this->url->export = sprintf("/events/export/date/%d.ics", $this->id);
     $this->setAuthor(UserFactory::CreateUser($row['user_id']));
     if ($row['start'] != "00:00:00") {
         $this->Start = new DateTime($row['date'] . " " . $row['start']);
     }
     if ($row['end'] != "00:00:00") {
         $this->End = new DateTime($row['date'] . " " . $row['end']);
     }
     if (isset($this->meta['lat']) && empty($this->meta['lat'])) {
         unset($this->meta['lat']);
     }
     if (isset($this->meta['lon']) && empty($this->meta['lon'])) {
         unset($this->meta['lon']);
     }
     if (isset($this->meta['lat']) && isset($this->meta['lon'])) {
         $this->Place = Place::Factory($this->meta['lat'], $this->meta['lon']);
     }
     try {
         if ($this->Event->Place instanceof Place && !empty($this->Event->Place->Region->timezone)) {
             $this->Date->setTimezone(new DateTimeZone($this->Event->Place->Region->timezone));
             if ($this->Start instanceof DateTime) {
                 $this->Start->setTimezone(new DateTimeZone($this->Event->Place->Region->timezone));
             }
             if ($this->End instanceof DateTime) {
                 $this->End->setTimezone(new DateTimeZone($this->Event->Place->Region->timezone));
             }
         }
     } catch (Exception $e) {
         printArray($e->getMessage());
         printArray($this->Event->Place->Region->timezone);
     }
 }
Beispiel #8
0
 /**
  * Load the download data from the database and populate this class
  * @since Version 3.2
  * @return boolean
  */
 public function fetch()
 {
     if (empty($this->id)) {
         throw new Exception("Cannot fetch download object - no download ID given");
     }
     $query = "SELECT d.*, UNIX_TIMESTAMP(d.date) AS date_unix FROM download_items AS d WHERE d.id = ?";
     $row = $this->db->fetchRow($query, $this->id);
     if (!is_array($row) || count($row) === 0) {
         throw new Exception("Requested download not found");
     }
     // Populate the vars
     $this->name = $row['title'];
     $this->desc = $row['description'];
     $this->url_file = $row['url'];
     $this->filename = empty($row['filename']) ? basename($row['url']) : $row['filename'];
     $this->Date = new DateTime($row['date'], new DateTimeZone("Australia/Melbourne"));
     $this->hits = $row['hits'];
     $this->filesize = isset($row['filesize']) && $row['filesize'] > 0 ? formatBytes($row['filesize']) : "Unknown";
     $this->user_id = $row['user_id'];
     $this->filepath = $row['filepath'];
     $this->object_id = $row['object_id'];
     $this->approved = $row['approved'];
     $this->active = $row['active'];
     $this->extra_data = $row['extra_data'];
     $this->mime = $row['mime'];
     if (empty($this->filepath) && !empty($this->url_file)) {
         $pathinfo = parse_url($this->url_file);
         $this->filepath = str_replace("/uploads/", "", $pathinfo['path']);
         try {
             $this->commit();
         } catch (Exception $e) {
             // Do nothing
         }
     }
     if (!preg_match("@^(http|https)://@", $this->url_file)) {
         $this->url_file = parent::DOWNLOAD_HOST . parent::DOWNLOAD_DIR . $this->url_file;
     }
     if ($row['date'] == "0000-00-00 00:00:00") {
         $this->Date = new DateTime("now", new DateTimeZone("Australia/Melbourne"));
         $this->commit();
     }
     if (empty($this->user_id) && !empty($row['submitter'])) {
         $this->submitter = $row['submitter'];
     }
     /**
      * Load the category this download belongs to
      */
     $this->Category = new Category($row['category_id']);
     /**
      * Load the author
      */
     $this->Author = UserFactory::CreateUser($this->user_id);
     if (empty($this->mime) && file_exists(RP_DOWNLOAD_DIR . $this->filepath)) {
         $finfo = finfo_open(FILEINFO_MIME_TYPE);
         $this->mime = finfo_file($finfo, RP_DOWNLOAD_DIR . $this->filepath);
         $this->commit();
     }
     $this->url = Utility\DownloadUtility::buildUrls($this);
 }
Beispiel #9
0
 /**
  * Populate this object
  * @since Version 3.9.1
  * @return void
  */
 private function populate()
 {
     if (!($row = $this->Memcached->fetch($this->mckey))) {
         $query = "SELECT * FROM glossary WHERE id = ?";
         $row = $this->db->fetchRow($query, $this->id);
         $this->Memcached->save($this->mckey, $row);
     }
     if (!isset($row) || !is_array($row)) {
         return;
     }
     $this->name = $row['short'];
     $this->text = $row['full'];
     $this->example = $row['example'];
     $this->Type = new Type($row['type']);
     $this->status = isset($row['status']) ? $row['status'] : self::STATUS_APPROVED;
     $this->slug = $row['slug'];
     $this->setAuthor(UserFactory::CreateUser($row['author']));
     if ($row['date'] == "0000-00-00 00:00:00") {
         $this->Date = new DateTime();
         $this->commit();
     }
     if (!$this->Date instanceof DateTime) {
         $this->Date = new DateTime($row['date']);
     }
     $this->makeURLs();
     $this->makeSlug();
 }
Beispiel #10
0
 /**
  * Populate this object
  * @since Version 3.9.1
  * @return void
  * @param int|string $id
  */
 private function populate($id)
 {
     $row = $this->load($id);
     if (!isset($row) || !is_array($row)) {
         return;
     }
     $this->title = $row['title'];
     $this->desc = $row['description'];
     $this->meta = json_decode($row['meta'], true);
     $this->slug = $row['slug'];
     $this->status = isset($row['status']) ? $row['status'] : Events::STATUS_APPROVED;
     if (!isset($row['user_id'])) {
         $row['user_id'] = 45;
     }
     $this->setAuthor(UserFactory::CreateUser($row['user_id']));
     $this->flickr_tag = "railpage:event=" . $this->id;
     if (filter_var($row['category_id'], FILTER_VALIDATE_INT)) {
         $this->Category = Factory::CreateEventCategory($row['category_id']);
     }
     if (filter_var($row['organisation_id'], FILTER_VALIDATE_INT)) {
         $this->Organisation = OrganisationsFactory::CreateOrganisation($row['organisation_id']);
     }
     if (!empty($row['lat']) && round($row['lat'], 3) != "0.000" && !empty($row['lon']) && round($row['lon'], 3) != "0.000") {
         $this->Place = Place::Factory($row['lat'], $row['lon']);
     }
     $this->createUrls();
     $this->Templates = new stdClass();
     $this->Templates->view = sprintf("%s/event.tpl", $this->Module->Paths->html);
 }
 /**
  * Send out a notification to site admins to cast a deciding vote in the event of a tied competition
  * @since Version 3.10.0
  * @param \Railpage\Images\Competition $photoComp
  * @return void
  */
 public static function NotifyTied(Competition $photoComp)
 {
     if (isset($photoComp->meta['notifytied']) && $photoComp->meta['notifytied'] >= strtotime("-1 day")) {
         return;
     }
     $photoComp->meta['notifytied'] = time();
     $photoComp->commit();
     $Smarty = AppCore::GetSmarty();
     // User who will cast the deciding vote
     $Decider = UserFactory::CreateUser(45);
     // Create the push notification
     $Push = new Notification();
     $Push->transport = Notifications::TRANSPORT_PUSH;
     $Push->subject = "Tied photo competition";
     $Push->body = sprintf("The %s photo competition is tied. Cast a deciding vote ASAP.", $photoComp->title);
     $Push->setActionUrl($photoComp->url->tied)->addRecipient($Decider->id, $Decider->username, $Decider->username);
     $Push->commit()->dispatch();
     // Create an email notification as a backup
     $Email = new Notification();
     $Email->subject = "Tied competition: " . $photoComp->title;
     $Email->addRecipient($Decider->id, $Decider->username, $Decider->username);
     $tpl = $Smarty->ResolveTemplate("template.generic");
     $email = array("subject" => $Email->subject, "subtitle" => "Photo competitions", "body" => sprintf("<p>The <a href='%s'>%s</a>photo competition is tied and requires a deciding vote. <a href='%s'>Cast it ASAP</a>.</p>", $photoComp->url->canonical, $photoComp->title, $photoComp->url->tied));
     $Smarty->Assign("email", $email);
     $Email->body = $Smarty->fetch($tpl);
     $Email->commit();
     return;
 }
Beispiel #12
0
 /**
  * Populate this object
  * @since Version 3.9.1
  * @return void
  */
 private function populate($id)
 {
     $query = "SELECT * FROM loco_unit_corrections WHERE correction_id = ?";
     $row = $this->db->fetchRow($query, $id);
     if (count($row)) {
         $this->id = $id;
         $this->text = $row['text'];
         $this->User = UserFactory::CreateUser($row['user_id']);
         $this->Date = new DateTime($row['date']);
         $this->status = $row['status'];
         $this->Resolution = new stdClass();
         if (filter_var($row['resolved_by'], FILTER_VALIDATE_INT)) {
             $this->Resolution->User = UserFactory::CreateUser($row['resolved_by']);
             $this->Resolution->Date = new DateTime($row['resolved_date']);
         }
         if ($loco_id = filter_var($row['loco_id'], FILTER_VALIDATE_INT)) {
             $this->Object = new Locomotive($loco_id);
             return;
         }
         if ($class_id = filter_var($row['class_id'], FILTER_VALIDATE_INT)) {
             $this->Object = new LocoClass($class_id);
             return;
         }
     }
     throw new Exception("Unable to determine if this correction belongs to a locomotive or a locomotive class");
 }
Beispiel #13
0
 /**
  * Unban user
  * @since Version 3.2
  * @version 3.2
  * @param int $banId
  * @param int|bool $userId
  * @return boolean
  */
 public function unBanUser($banId, $userId = null)
 {
     $success = false;
     /**
      * Empty the cache
      */
     try {
         $this->Memcached->delete("railpage:bancontrol.users");
         $this->Memcached->delete(self::CACHE_KEY_ALL);
     } catch (Exception $e) {
         // throw it away
     }
     try {
         $this->Redis->delete("railpage:bancontrol");
     } catch (Exception $e) {
         // throw it away
     }
     if ($banId instanceof User) {
         $userId = $banId->id;
     }
     if ($userId == null) {
         $query = "SELECT user_id FROM bancontrol WHERE id = ?";
         $userId = $this->db->fetchOne($query, $banId);
     }
     if ($userId > 0) {
         $data = array("ban_active" => 0);
         $where = array("user_id = " . $userId);
         $this->db->update("bancontrol", $data, $where);
         $success = true;
         $cachekey_user = sprintf(self::CACHE_KEY_USER, $userId);
         $this->Memcached->save($cachekey_user, false, strtotime("+5 weeks"));
     }
     if ($success) {
         // Tell the world that they've been unbanned
         $ThisUser = UserFactory::CreateUser($userId);
         $ThisUser->active = 1;
         $ThisUser->location = "";
         $ThisUser->signature = "";
         $ThisUser->avatar = "";
         $ThisUser->interests = "";
         $ThisUser->occupation = "";
         try {
             $ThisUser->commit();
             $Smarty = AppCore::getSmarty();
             // Send the ban email
             $Smarty->Assign("userdata_username", $ThisUser->username);
             // Send the confirmation email
             $Notification = new Notification();
             $Notification->addRecipient($ThisUser->id, $ThisUser->username, $ThisUser->contact_email);
             $Notification->body = $Smarty->Fetch($Smarty->ResolveTemplate("email_unban"));
             $Notification->subject = "Railpage account re-activation";
             $Notification->transport = Notifications::TRANSPORT_EMAIL;
             $Notification->commit()->dispatch();
             return true;
         } catch (Exception $e) {
             global $Error;
             if (isset($Error)) {
                 $Error->save($e, $_SESSION['user_id']);
             }
             Debug::logException($e);
         }
     }
     return false;
 }
Beispiel #14
0
 /**
  * Find user from email address
  * @since Version 3.8.7
  * @param string $email
  * @param string $provider
  * @author Michael Greenhill
  */
 public function getUserFromEmail($email = null, $provider = "railpage")
 {
     if ($email == null) {
         throw new Exception("Can't find user - no email address provided");
     }
     $query = "SELECT user_id FROM nuke_users WHERE user_email = ?";
     $params = array($email);
     if (!is_null($provider)) {
         $params[] = $provider;
         $query .= " AND provider = ?";
     }
     $user_id = $this->db->fetchOne($query, $params);
     if (filter_var($user_id, FILTER_VALIDATE_INT)) {
         return Factory::CreateUser($user_id);
     }
     throw new Exception(sprintf("No user found with an email address of %s and logging in via %s", $email, $provider));
 }
Beispiel #15
0
 /**
  * Populate this object
  * @since Version 3.9.1
  * @param string $column
  * @param string|int $value
  * @return void
  */
 private function populate($column, $value)
 {
     $query = sprintf("SELECT * FROM idea_ideas WHERE %s = ?", $column);
     if (!($row = $this->db->fetchRow($query, $value))) {
         return;
     }
     $this->title = $row['title'];
     $this->id = $row['id'];
     $this->slug = $row['slug'];
     $this->description = $row['description'];
     $this->Date = new DateTime($row['date']);
     $this->Category = new Category($row['category_id']);
     $this->status = $row['status'];
     $this->forum_thread_id = $row['forum_thread_id'];
     $this->redmine_id = $row['redmine_id'];
     $this->meta = json_decode($row['meta'], true);
     if (!is_array($this->meta)) {
         $this->meta = [];
     }
     $this->setAuthor(UserFactory::CreateUser($row['author']));
     $this->fetchVotes();
     $this->makeURLs();
 }
Beispiel #16
0
 /**
  * Approve user membership
  * @since Version 3.9.1
  * @param \Railpage\Users\User|int $userObject
  * @return \Railpage\Users\Group
  */
 public function approveUser($userObject)
 {
     if (!$userObject instanceof User) {
         $userObject = Factory::CreateUser($userObject);
     }
     $data = ["user_pending" => 0];
     $where = ["user_id = ?" => $userObject->id, "group_id = ?" => $this->id];
     $mckey = sprintf("railpage:group=%d", intval($this->id));
     $this->Redis->delete($mckey);
     $this->db->update("nuke_bbuser_group", $data, $where);
     return $this;
 }
Beispiel #17
0
 /**
  * Validate a password for this account
  *
  * Updated to use PHP 5.5's password_hash(), password_verify() and password_needs_rehash() functions
  * @since Version 3.8.7
  *
  * @param string $password
  *
  * @return boolean
  */
 public function validatePassword($password = false, $username = false)
 {
     Utility\PasswordUtility::validateParameters($password, $username, $this);
     /**
      * Create a temporary instance of the requested user for logging purposes
      */
     try {
         $TmpUser = Factory::CreateUserFromUsername($username);
     } catch (Exception $e) {
         if ($e->getMessage() == "Could not find user ID from given username") {
             $TmpUser = new User($this->id);
         }
     }
     /**
      * Get the stored password for this username
      */
     if ($username && !empty($username) && empty($this->username)) {
         $query = "SELECT user_id, user_password, user_password_bcrypt FROM nuke_users WHERE username = ?";
         $row = $this->db->fetchRow($query, $username);
         $stored_user_id = $row['user_id'];
         $stored_pass = $row['user_password'];
         $stored_pass_bcrypt = $row['user_password_bcrypt'];
     } elseif (!empty($this->password)) {
         $stored_user_id = $this->id;
         $stored_pass = $this->password;
         $stored_pass_bcrypt = $this->password_bcrypt;
     }
     /**
      * Check if the invalid auth timeout is in effect
      */
     if (isset($TmpUser->meta['InvalidAuthTimeout'])) {
         if ($TmpUser->meta['InvalidAuthTimeout'] <= time()) {
             unset($TmpUser->meta['InvalidAuthTimeout']);
             unset($TmpUser->meta['InvalidAuthCounter']);
             $TmpUser->commit();
             $this->refresh();
         } else {
             $TmpUser->addNote("Login attempt while InvalidAuthTimeout is in effect");
             throw new Exception("You've attempted to log in with the wrong password too many times. We've temporarily disabled your account to protect it against hackers. Please try again soon. <a href='/account/resetpassword'>Can't remember your password?</a>");
         }
     }
     /**
      * Verify the password
      */
     if (Utility\PasswordUtility::validatePassword($password, $stored_pass, $stored_pass_bcrypt)) {
         $this->load($stored_user_id);
         /**
          * Check if the password needs rehashing
          */
         if (password_needs_rehash($stored_pass, PASSWORD_DEFAULT) || password_needs_rehash($stored_pass_bcrypt, PASSWORD_DEFAULT)) {
             $this->setPassword($password);
         }
         /**
          * Reset the InvalidAuthCounter
          */
         if (isset($this->meta['InvalidAuthCounter'])) {
             unset($this->meta['InvalidAuthCounter']);
         }
         if (isset($this->meta['InvalidAuthTimeout'])) {
             unset($this->meta['InvalidAuthTimeout']);
         }
         $this->commit();
         return true;
     }
     /**
      * Unsuccessful login attempt - bump up the invalid auth counter
      */
     $TmpUser->meta['InvalidAuthCounter'] = !isset($TmpUser->meta['InvalidAuthCounter']) ? 1 : $TmpUser->meta['InvalidAuthCounter']++;
     $TmpUser->addNote(sprintf("Invalid login attempt %d", $TmpUser->meta['InvalidAuthCounter']));
     $TmpUser->commit();
     $this->refresh();
     if ($TmpUser->meta['InvalidAuthCounter'] === 3) {
         $TmpUser->meta['InvalidAuthTimeout'] = strtotime("+10 minutes");
         $TmpUser->addNote("Too many invalid login attempts - account disabled for ten minutes");
         $TmpUser->commit();
         $this->refresh();
         throw new Exception("You've attempted to log in with the wrong password too many times. As a result, we're disabling this account for the next ten minutes. <a href='/account/resetpassword'>Can't remember your password?</a>");
     }
     $this->reset();
     return false;
 }
Beispiel #18
0
 /**
  * Get all open corrections
  * @since Version 3.9.1
  * @return array
  */
 public function getOpenCorrections()
 {
     $query = "SELECT l.name AS location_name, u.username, c.* \n                    FROM location_corrections AS c \n                    LEFT JOIN location AS l ON c.location_id = l.id \n                    LEFT JOIN nuke_users AS u ON u.user_id = c.user_id \n                    WHERE c.status = ? \n                    ORDER BY c.date_added DESC";
     $return = array();
     foreach ($this->db->fetchAll($query, Correction::STATUS_NEW) as $row) {
         $return[] = array("location" => (new Location($row['location_id']))->getArray(), "author" => UsersFactory::CreateUser($row['user_id'])->getArray(), "correction" => array("comments" => $row['comments'], "date" => array("added" => $row['date_added'], "closed" => $row['date_closed'])));
     }
     return $return;
 }
Beispiel #19
0
 /**
  * Save a correction for this loco
  * @since Version 3.2
  * @param string $text
  * @param int $userId
  */
 public function newCorrection($text = false, $userId = false)
 {
     $Correction = new Correction();
     $Correction->text = $text;
     $Correction->setUser(UserFactory::CreateUser($userId));
     $Correction->setObject($this);
     $Correction->commit();
     return true;
 }
Beispiel #20
0
 /**
  * Get and personalise the content for this newsletter
  * @since Version 3.10.0
  * @return \Railpage\Newsletters\Weekly
  */
 private function personaliseContent()
 {
     $replacements = array();
     Debug::LogCLI("Looping through " . count($this->recipients) . " users and preparing email decoration");
     $this->user_ids = array();
     $counter = 0;
     /**
      * Loop through our list of users and start to curate the contents
      */
     foreach ($this->recipients as $row) {
         // Flag this user ID so that we can update the "last sent" timestamp later
         $user_ids[] = $row['user_id'];
         // Sanity check : validate the email address first
         if (!filter_var($row['user_email'], FILTER_VALIDATE_EMAIL)) {
             Debug::LogCLI("Skipping user ID " . $row['user_id'] . " - \"" . $row['user_email'] . "\" is not a valid email address");
             continue;
         }
         // Add the recipient
         $this->Notification->addRecipient($row['user_id'], $row['username'], $row['user_email']);
         // Assign some decoration
         $replacements[$row['user_email']] = array("##username##" => $row['username'], "##email##" => $row['user_email'], "##email_encoded##" => urlencode($row['user_email']), "##unsubscribe##" => sprintf("http://railpage.com.au/unsubscribe?email=%s&newsletter=weekly", urlencode($row['user_email'])));
         /**
          * Get the custom news feed articles
          */
         Debug::LogCLI("Preparing personalised news for user ID " . $row['user_id']);
         // Try and create the user object. If it bombs out, we need to know about it but let the newsletter continue
         try {
             $User = UserFactory::CreateUser($row['user_id']);
         } catch (Exception $e) {
             Debug::LogCLI("Skipped user due to exception: " . $e->getMessage());
             continue;
         }
         // Create the custom news feed object
         $Feed = new Feed();
         $Feed->setUser($User);
         $articles = $Feed->addFilter(Feed::FILTER_UNREAD)->addFilter(Feed::FILTER_LAST_30_DAYS)->findArticles(0, 10, "story_hits");
         // If the number of personalised articles is less than ten, drop the filter and simply find ten recent and unread articles
         if (count($articles) < 10) {
             Debug::LogCLI("Found " . count($articles) . " articles for user ID " . $User->id . " - dropping keyword and topic filter from feed");
             $Feed->filter_words = null;
             $Feed->filter_topics = null;
             $articles = $Feed->findArticles(0, 10, "story_hits");
         }
         // If we have less than six articles skip this user altogether.
         if (count($articles) < 6) {
             Debug::LogCLI("Found " . count($articles) . " articles for user ID " . $User->id . " - skipping");
             continue;
         }
         Debug::LogCLI("Proceeding with newsletter for user ID " . $User->id);
         // Loop through each article and normalise the content
         foreach ($articles as $id => $article) {
             $article['sid'] = $article['story_id'];
             $article['catid'] = $article['topic_id'];
             $article['hometext'] = preg_replace("@(\\[b\\]|\\[\\/b\\])@", "", $article['story_blurb']);
             $article['informant'] = $article['username'];
             $article['informant_id'] = $article['user_id'];
             $article['ForumThreadId'] = $article['forum_topic_id'];
             $article['topictext'] = ContentUtility::FormatTitle($article['topic_title']);
             $article['topic'] = $article['topic_id'];
             $article['featured_image'] = ImageCache::cache($article['story_image']);
             $article['title'] = $article['story_title'];
             $article['url'] = NewsletterUtility::CreateUTMParametersForLink($this->Newsletter, $article['url']);
             $articles[$id] = $article;
         }
         $articles = array_values($articles);
         if (!isset($start)) {
             $start = 0;
         }
         // Loop through the prepended content and assign it to the blocks
         foreach ($this->prependedContent as $i => $block) {
             $tmp = ["##block" . $i . ".subtitle##" => $block['title'], "##block" . $i . ".featuredimage##" => $block['featuredimage'], "##block" . $i . ".text##" => strip_tags(wpautop(process_bbcode($block['text'])), "<br><br /><p>"), "##block" . $i . ".link##" => strpos($block['url'], "http") === false ? "http://www.railpage.com.au" . $block['url'] : $block['url'], "##block" . $i . ".alt_title##" => $block['subtitle'], "##block" . $i . ".link_text##" => isset($block['link_text']) && !empty($block['link_text']) ? $block['link_text'] : "Continue reading"];
             $replacements[$row['user_email']] = array_merge($replacements[$row['user_email']], $tmp);
         }
         // Loop through our content and assign to content blocks
         for ($i = count($this->prependedContent) + $start; $i < $start + $this->num_items; $i++) {
             $Date = new DateTime($articles[$i]['story_time']);
             $tmp = ["##block" . $i . ".subtitle##" => $articles[$i]['story_title'], "##block" . $i . ".featuredimage##" => $articles[$i]['story_image'], "##block" . $i . ".text##" => strip_tags(wpautop(process_bbcode($articles[$i]['story_lead'])), "<br><br /><p>"), "##block" . $i . ".link##" => strpos($articles[$i]['url'], "http") === false ? "http://www.railpage.com.au" . $articles[$i]['url'] : $articles[$i]['url'], "##block" . $i . ".alt_title##" => sprintf("Published %s", $Date->format("F j, Y, g:i a")), "##block" . $i . ".link_text##" => "Continue reading"];
             $replacements[$row['user_email']] = array_merge($replacements[$row['user_email']], $tmp);
         }
         Debug::LogCLI("Completed personalisation of newsletter for user ID " . $User->id);
         // Increment our personalised newsletter counter
         $counter++;
         /**
          * Break after 150 recipients. Don't want to be flagged as a spammer, or overload the MTA
          */
         if ($counter == 150) {
             break;
         }
     }
     $this->replacements = $replacements;
     return $this;
 }
Beispiel #21
0
 /**
  * Get author of a submitted photo
  * @since Version 3.9.1
  * @return \Railpage\Users\User
  * @param \Railpage\Images\Image $imageObject
  */
 public function getPhotoAuthor(Image $imageObject)
 {
     $query = "SELECT user_id FROM image_competition_submissions WHERE competition_id = ? AND image_id = ?";
     $params = array($this->id, $imageObject->id);
     #printArray($params);die;
     $user_id = $this->db->fetchOne($query, $params);
     return UserFactory::CreateUser($user_id);
 }
Beispiel #22
0
 /**
  * Populate this object
  *
  * @since Version 3.9.1
  * @return void
  */
 private function load()
 {
     if (!($row = $this->db->fetchRow("SELECT * FROM asset WHERE id = ?", $this->id))) {
         return;
     }
     $this->hash = $row['hash'];
     $this->type_id = $row['type_id'];
     $this->meta = json_decode($row['meta'], true);
     if (function_exists("get_domain")) {
         $this->meta['domain'] = get_domain($this->meta['url']);
     }
     $this->url = new Url("/assets?id=" . $this->id);
     foreach ($this->meta as $key => $val) {
         if (is_string($val)) {
             $this->meta[$key] = trim($val);
         }
         if (is_array($val)) {
             foreach ($val as $k => $v) {
                 if (is_string($v)) {
                     $this->meta[$key][$k] = trim($v);
                 }
             }
         }
     }
     /**
      * Update the unique hash if we need to
      */
     if (empty($this->hash)) {
         $data = array("hash" => md5($this->meta['url']));
         $where = array("id = ?" => $this->id);
         $this->db->update("asset", $data, $where);
     }
     /**
      * Get uses/instances from the database
      */
     foreach ($this->db->fetchAll("SELECT * FROM asset_link WHERE asset_id = ? ORDER BY date DESC", $this->id) as $row) {
         $this->instances[$row['asset_link_id']] = $row;
         $this->Date = new DateTime($row['date']);
         $this->User = UserFactory::CreateUser($row['user_id']);
     }
 }
Beispiel #23
0
 /**
  * Load the owner of this album
  * @since Version 3.8.7
  * @return \Railpage\Users\User
  */
 public function getOwner()
 {
     if ($this->Owner instanceof User) {
         return $this->Owner;
     }
     if (filter_var($this->owner, FILTER_VALIDATE_INT)) {
         try {
             return UserFactory::CreateUser($this->owner);
         } catch (Exception $e) {
             // Don't care
         }
     }
 }
Beispiel #24
0
 /**
  * Load the author
  * @since Version 3.8.7
  * @return $this
  */
 public function loadAuthor()
 {
     $this->Author = UserFactory::CreateUser($this->uid);
     return $this;
 }
Beispiel #25
0
 /**
  * Get watchers of this thread
  * @since Version 3.9
  * @return array
  */
 public function getWatchers()
 {
     $query = "SELECT w.user_id FROM nuke_bbtopics_watch AS w LEFT JOIN nuke_users AS u ON u.user_id = w.user_id WHERE w.topic_id = ? ORDER BY u.username";
     $return = array();
     foreach ($this->db->fetchAll($query, $this->id) as $row) {
         $ThisUser = UserFactory::CreateUser($row['user_id']);
         $row = array("id" => $ThisUser->id, "username" => $ThisUser->username, "url" => $ThisUser->url->getUrls());
         $return[] = $row;
     }
     return $return;
 }
Beispiel #26
0
 /**
  * Validate changes to an article before committing changes
  * @since Version 3.4
  * @return boolean
  * @throws \Exception if the article title is empty
  * @throws \Exception if the article blurb and lead are empty
  * @throws \Exception if the body and paragraphs AND source are empty
  * @throws \Exception if the article title is too long
  */
 public function validate()
 {
     if (empty($this->title)) {
         throw new Exception("Validation failed: title is empty");
     }
     if (empty($this->blurb) && empty($this->lead)) {
         throw new Exception("Validation failed: blurb is empty");
     }
     if (empty($this->body) && empty($this->source) && empty($this->paragraphs)) {
         throw new Exception("Validation failed: body is empty");
     }
     if (is_null($this->blurb) || !empty($this->lead)) {
         $this->blurb = "";
     }
     if (is_null($this->body) || !empty($this->paragraphs)) {
         $this->body = "";
     }
     if (is_null($this->paragraphs)) {
         $this->paragraphs = "";
     }
     if (is_null($this->lead)) {
         $this->lead = "";
     }
     if (!isset($this->Author) || !$this->Author instanceof User) {
         $this->Author = UserFactory::CreateUser($this->user_id);
     }
     if (!$this->date instanceof DateTime) {
         $this->date = new DateTime();
     }
     if (!filter_var($this->approved)) {
         $this->approved = self::STATUS_UNAPPROVED;
     }
     if (is_null($this->source)) {
         $this->source = "";
     }
     if (empty($this->unique_id)) {
         $this->unique_id = md5($this->title);
     }
     if (!is_bool($this->queued)) {
         $this->queued = false;
     }
     /**
      * Try to get the featured image from OpenGraph tags
      */
     if ($this->source && !$this->featured_image) {
         require_once "vendor" . DS . "scottmac" . DS . "opengraph" . DS . "OpenGraph.php";
         $graph = \OpenGraph::fetch($this->source);
         #printArray($graph->keys());
         #printArray($graph->schema);
         foreach ($graph as $key => $value) {
             if ($key == "image" && strlen($value) > 0) {
                 $this->featured_image = $value;
             }
         }
     }
     return true;
 }
Beispiel #27
0
 /**
  * Constructor
  *
  * @since Version 3.8.7
  *
  * @param int|bool $id
  *
  * @returns \Railpage\Warnings\Warning
  */
 public function __construct($id = null)
 {
     parent::__construct();
     if (!($id = filter_var($id, FILTER_VALIDATE_INT))) {
         return $this;
     }
     $this->id = $id;
     $query = "SELECT * FROM phpbb_warnings WHERE warn_id = ?";
     if ($row = $this->db->fetchRow($query, $this->id)) {
         $this->level = $row['new_warning_level'];
         $this->adjustment = $row['new_warning_level'] - $row['old_warning_level'];
         $this->reason = $row['warn_reason'];
         $this->action = $row['actiontaken'];
         $this->comments = $row['mod_comments'];
         $this->Date = new DateTime("@" . $row['warn_date']);
         $this->Recipient = UserFactory::CreateUser($row['user_id']);
         $this->Issuer = UserFactory::CreateUser($row['warned_by']);
     }
     return $this;
 }
Beispiel #28
0
 /**
  * Populate this object
  * @since Version 3.9.1
  * @return void
  */
 private function load()
 {
     $query = "SELECT * FROM image_collection WHERE id = ?";
     $row = $this->db->fetchRow($query, $this->id);
     $this->slug = $row['slug'];
     $this->name = $row['title'];
     $this->description = $row['description'];
     $this->DateCreated = new DateTime($row['created'], new DateTimeZone("Australia/Melbourne"));
     $this->DateModified = new DateTime($row['modified'], new DateTimeZone("Australia/Melbourne"));
     $this->setAuthor(UsersFactory::CreateUser($row['user_id']));
     /*
     if (empty($this->slug) || $this->slug == 1) {
         $this->validate(); 
         $this->commit(); 
     }
     */
     $this->makeURLs();
     return;
 }