/**
  * Add activity metadata 
  * 
  * @param User $user
  * @param Activity $activity
  * @param array $data    key-value pair data to store
  * @param array $exclude When given exclude keys to be stored in the database
  */
 public static function addUserActivity(User $user, Activity $activity, array $data, array $exclude = [])
 {
     $rows = [];
     $exclude = array_map('strtolower', $exclude);
     // Create a session_id.
     // Session_id is use for easily identify groups of metadata
     $hashids = new Hashids('dma.activity.metadata', 6);
     $user_id = $user->getKey();
     $activity_id = $activity->getKey();
     // Add unixtime and microseconds to avoid session_id collisions
     $micro = microtime(true);
     $unixtime = floor($micro);
     $milseconds = floor(($micro - $unixtime) * pow(10, 8));
     // Create session_id
     $session_id = $hashids->encode($user_id, $activity_id, $unixtime, $milseconds);
     // Current date and time
     $now = date('Y-m-d H:i:s');
     foreach ($data as $key => $value) {
         $key = strtolower($key);
         if (!in_array($key, $exclude)) {
             $row = ['session_id' => $session_id, 'user_id' => $user_id, 'activity_id' => $activity_id, 'key' => $key, 'value' => $value, 'created_at' => $now, 'updated_at' => $now];
             $rows[] = $row;
         }
     }
     if (count($row) > 0) {
         static::insert($rows);
     }
 }
 /**
  * Take an activity and apply it to any badges and steps that apply
  *
  * @param User $user
  * A user model
  * @param Activity $activity 
  * An activity model
  */
 public static function applyActivityToBadges(User $user, Activity $activity)
 {
     $steps = $activity->steps()->get();
     foreach ($steps as $step) {
         // user has not completed the step
         $isStepCompletable = self::checkUserActivities($user, $activity, $step);
         if ($isStepCompletable) {
             // Find badge associated with steps
             self::completeBadge($step, $user);
         }
     }
 }
 /**
  * {%inheritDoc}
  */
 public static function process(User $user, $params = [])
 {
     if (!isset($params['code']) || empty($params['code'])) {
         return false;
     }
     if ($activity = Activity::findActivityType('LikeWorkOfArt')->first()) {
         $code = $params['code'];
         if ($data = self::isAssessionNumber($code)) {
             // Skip activity process if user has already like this work of art
             $likeCount = ActivityMetadata::hasMetadataValue($user, $activity, 'object_id', $data['object_id'])->count();
             if ($likeCount == 0) {
                 // User haven't like this artwork yet
                 if ($ret = parent::process($user, ['activity' => $activity])) {
                     // TODO: Find a better way to pass this data
                     $activity->objectData = $data;
                     // Save user metada activity
                     ActivityMetadata::addUserActivity($user, $activity, $data, ['object_title']);
                     FriendsLog::artwork(['user' => $user, 'artwork_id' => $params['code']]);
                 }
                 return $ret;
             } else {
                 Session::put('activityError', Lang::get('dma.friends::lang.activities.alreadyLikeWorkArtError', ['code' => $params['code']]));
             }
         } else {
             // Verify if user try to enter an Object number
             // Regex expression to match object number format
             $re = "/((([a-zA-Z0-9_\\-]+\\.){1,})([a-zA-Z0-9_\\-]+))/";
             $isObjectNumber = preg_match_all($re, str_replace(' ', '', $code)) > 0;
             if ($isObjectNumber) {
                 Session::put('activityError', Lang::get('dma.friends::lang.activities.likeWorkArtCodeError', ['code' => $params['code']]));
             }
         }
     }
     return false;
 }
 public function testTimeRestrictionsAreSerialized()
 {
     $activity = FactoryMuffin::create('DMA\\Friends\\Models\\Activity');
     $timeRestrictionData = ['start_time' => '11:00AM', 'end_time' => '12:00PM', 'days' => [1 => true, 2 => false, 3 => true, 4 => false, 5 => true, 6 => false]];
     $activity->time_restriction_data = $timeRestrictionData;
     $activity->save();
     // Load a new reference to the model
     $newActivity = Activity::find($activity->id);
     // Compare time_restriction_data to ensure that attributes are serialized/unserialized properly
     $this->assertEquals($newActivity->time_restriction_data, $timeRestrictionData);
 }
 /**
  * {@inheritDoc}
  */
 public static function process(User $user, $params = [])
 {
     $activities = Activity::where('activity_type', '=', 'Registration')->get();
     if (!$activities) {
         return;
     }
     foreach ($activities as $activity) {
         parent::process($user, ['activity' => $activity]);
     }
     return true;
 }
 /**
  * @see \DMA\Friends\Classes\ActivityTypeBase
  *
  * Process and determine if an award can be isued
  * based on a provided activity code
  *
  * @param User $user
  * A user model for which the activity should act upon
  * 
  * @param array $params
  * An array of parameters for validating activities 
  *
  * @return boolean
  * returns true if the process was successful
  */
 public static function process(User $user, $params = [])
 {
     if (!isset($params['code']) || empty($params['code'])) {
         return false;
     }
     if ($activity = Activity::findCode($params['code'])->first()) {
         return parent::process($user, ['activity' => $activity]);
     }
     Session::put('activityError', Lang::get('dma.friends::lang.activities.codeError', ['code' => $params['code']]));
     return false;
 }
 /** 
  * Run the migrations.
  *
  * @return void
  */
 public function up()
 {
     Activity::chunk(200, function ($activities) {
         foreach ($activities as $activity) {
             if ($activity->date_begin && $activity->date_end) {
                 $activity->time_restriction = Activity::TIME_RESTRICT_DAYS;
             } elseif (!empty($activity->time_restriction_data)) {
                 $activity->time_restriction = Activity::TIME_RESTRICT_HOURS;
             } else {
                 $activity->time_restriction = Activity::TIME_RESTRICT_NONE;
             }
             $activity->save();
         }
     });
 }
 /**
  * Produce a collection of Activities based on recommendations and filters
  */
 private function getResults($filterstr = null)
 {
     $perpage = 12;
     if ($filterstr && $filterstr != 'all') {
         $filters = json_decode($filterstr, true);
         if ($filters && is_array($filters['categories'])) {
             $results = Activity::isActive()->byCategory($filters['categories'])->paginate($perpage);
         } else {
             $results = Activity::isActive()->paginate($perpage);
         }
     } else {
         $results = Activity::isActive()->paginate($perpage);
     }
     $this->page['activities'] = $results;
     $this->page['hasLinks'] = $results->hasMorePages() || $results->currentPage() > 1;
     $this->page['links'] = $results->render();
 }
Exemple #9
0
 /**
  * @see \DMA\Friends\Classes\ActivityTypeBase
  *
  * Process and determine if an award can be isued
  * based on a provided activity code
  *
  * @param User $user
  * A user model for which the activity should act upon
  * 
  * @param array $params
  * An array of parameters for validating activities 
  *
  * @return boolean
  * returns true if the process was successful
  */
 public static function process(User $user, $params = [])
 {
     static $is_running = false;
     if (!$is_running) {
         $is_running = true;
         $activities = Activity::findActivityType('Points')->get();
         foreach ($activities as $activity) {
             if ($user->activities->contains($activity->id)) {
                 continue;
             }
             if ($user->points >= $activity->points) {
                 parent::process($user, ['activity' => $activity]);
             }
         }
         $is_running = false;
     }
     return true;
 }
Exemple #10
0
 /**
  * {@inheritDoc}
  */
 public function boot()
 {
     // Extend Activity model to support extra fields & ratings
     Activity::extend(function ($model) {
         $model->hasOne['activity_fields'] = ['DenverArt\\ActivityFields\\Models\\ExtraFields'];
         $model->hasMany['ratings'] = ['DenverArt\\ActivityFields\\Models\\Rating'];
         $model->addDynamicMethod('scopeNotIgnored', function ($query, $user) {
             $query = $query->whereHas('ratings', function ($q) use($user) {
                 $q->where('user_id', $user->getKey())->where('rating', 0);
             }, '<', 1);
         });
         $model->addDynamicMethod('scopeIgnored', function ($query, $user) {
             $query = $query->whereHas('ratings', function ($q) use($user) {
                 $q->where('user_id', $user->getKey())->where('rating', 0);
             });
         });
         $model->addDynamicMethod('scopeNotComplete', function ($query, $user) {
             $query = $query->whereHas('users', function ($q) use($user) {
                 $q->where('user_id', $user->getKey());
             }, '<', 1);
         });
         $model->addDynamicMethod('scopeComplete', function ($query, $user) {
             $query = $query->whereHas('users', function ($q) use($user) {
                 $q->where('user_id', $user->getKey());
             });
         });
     });
     // Extend User model to support ratings
     User::extend(function ($model) {
         $model->hasMany['ratings'] = ['DenverArt\\ActivityFields\\Models\\Rating'];
     });
     // Extend Activity fields
     $context = $this;
     Event::listen('backend.form.extendFields', function ($widget) use($context) {
         $context->extendedActivityFields($widget);
     });
     // Extend Activity admin listing table columns
     Event::listen('backend.list.extendColumns', function ($widget) {
         if (!$widget->getController() instanceof \DMA\Friends\Controllers\Activities) {
             return;
         }
         $widget->addColumns(['duration' => ['label' => 'Duration', 'relation' => 'activity_fields', 'sortable' => true, 'select' => '@duration', 'searchable' => true], 'location' => ['label' => 'Location', 'relation' => 'activity_fields', 'sortable' => true, 'select' => '@location', 'searchable' => true]]);
     });
 }
 public function afterSave()
 {
     $activity = Activity::find($this->getKey());
     $activity->touch();
 }
 public function onUndoHide()
 {
     // Get submit data
     $activity_id = (int) post('activity');
     // Validate
     $activity = Activity::find($activity_id);
     if ($activity) {
         // Get User
         $user = Auth::getUser();
         Rating::where('activity_id', $activity_id)->where('user_id', $user->id)->delete();
         Flash::success('Okay. That activity will be available in your recommendations now.');
     } else {
         Flash::error('That activity does not exist.');
     }
     // return flash message
     return ['#flashMessages' => $this->renderPartial('@flashMessages')];
 }
 /** 
  * Determine if an activity is capable of being completed
  *
  * @param Activity
  * An activity model
  *
  * @return boolean
  * returns true if an activity can be completed by the user
  */
 public static function canComplete(Activity $activity, User $user)
 {
     if (!$activity->isActive()) {
         return false;
     }
     // Check activity lockout
     if ($activity->activity_lockout && ($pivot = $user->activities()->where('activity_id', $activity->id)->first())) {
         $time = Carbon::now();
         $lastTime = $pivot->pivot->created_at;
         if ($time->diffInMinutes($lastTime) < $activity->activity_lockout) {
             $x = $time->diffInMinutes($lastTime->addMinutes($activity->activity_lockout));
             $message = self::convertToHoursMins($x, '%d hours and %02d minutes');
             Session::put('activityError', Lang::get('dma.friends::lang.activities.lockout', ['x' => $message]));
             return false;
         }
     }
     switch ($activity->time_restriction) {
         case Activity::TIME_RESTRICT_NONE:
             return true;
         case Activity::TIME_RESTRICT_HOURS:
             if ($activity->time_restriction_data) {
                 $now = Carbon::now();
                 $start = self::convertTime($activity->time_restriction_data['start_time']);
                 $end = self::convertTime($activity->time_restriction_data['end_time']);
                 $start_time = Carbon::now();
                 $start_time->setTime($start['hour'], $start['minutes']);
                 $end_time = Carbon::now();
                 $end_time->setTime($end['hour'], $start['minutes']);
                 $day = date('w');
                 // Sunday is on the end of the week and date sets sunday as 0
                 if ($day == 0) {
                     $day = 7;
                 }
                 if ($activity->time_restriction_data['days'][$day] !== false && $now->gte($start_time) && $now->lte($end_time)) {
                     return true;
                 } else {
                     Session::put('activityError', Lang::get('dma.friends::lang.activities.notAvailable'));
                 }
             }
             break;
         case Activity::TIME_RESTRICT_DAYS:
             $now = new DateTime('now');
             if ($now >= $activity->date_begin && $now <= $activity->date_end) {
                 return true;
             } else {
                 Session::put('activityError', Lang::get('dma.friends::lang.activities.notAvailable'));
             }
             break;
     }
     return false;
 }
Exemple #14
0
 /**
  * Produce a collection of Activities based on recommendations and filters
  */
 private function getResults($filterstr = null)
 {
     $user = Auth::getUser();
     $perpage = 12;
     $dayNames = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
     $restrictions = [];
     if ($filterstr && $filterstr != 'all') {
         $filters = json_decode($filterstr, true);
         if ($filters && is_array($filters['categories'])) {
             $results = Activity::isActive()->ignored($user)->byCategory($filters['categories'])->paginate($perpage);
         } else {
             $results = Activity::isActive()->ignored($user)->paginate($perpage);
         }
     } else {
         $results = Activity::isActive()->ignored($user)->paginate($perpage);
     }
     foreach ($results as $index => $result) {
         $string = '';
         $type = $result->time_restriction;
         $time = $result->time_restriction_data;
         if ($type == 1) {
             $days = [];
             foreach ($time['days'] as $key => $value) {
                 if ($value > 0) {
                     $days[] .= $dayNames[$key - 1];
                 }
             }
             $len = count($days);
             switch ($len) {
                 case 0:
                     break;
                 case 1:
                     $string = $days[0];
                     break;
                 case 2:
                     $string = implode(' and ', $days);
                     break;
                 default:
                     $last = array_pop($days);
                     $string = implode(', ', $days) . ' and ' . $last;
             }
             $string .= ' at ';
             $string .= strtolower($time['start_time'] . '–' . $time['end_time']);
         } elseif ($type == 2) {
             $start = date('M j, Y', strtotime($result->date_begin));
             $end = date('M j, Y', strtotime($result->date_end));
             if ($start == $end) {
                 $start = date('M j, Y g:i a', strtotime($result->date_begin));
                 $end = date('M j, Y g:i a', strtotime($result->date_end));
                 if ($start == $end) {
                     $string = $start;
                 } else {
                     $end = date('g:i a', strtotime($result->date_end));
                 }
             }
             if (!$string) {
                 $string = $start . ' to ' . $end;
             }
         }
         $restrictions[$index] = $string;
     }
     $this->page['activities'] = $results;
     $this->page['activity_count'] = $results->count();
     $this->page['restrictions'] = $restrictions;
     $this->page['hasLinks'] = $results->hasMorePages() || $results->currentPage() > 1;
     $this->page['links'] = $results->render();
 }
 /** 
  * Execute the console command.
  * @return void
  */
 public function fire()
 {
     // Taxonomy terms
     $termRelations = $this->db->table('wp_term_relationships')->get();
     foreach ($termRelations as $relation) {
         $activity = Activity::findWordpress($relation->object_id)->first();
         if ($activity) {
             if (!$activity->categories->contains($relation->term_taxonomy_id)) {
                 $category = Category::find($relation->term_taxonomy_id);
                 if ($category) {
                     $activity->categories()->save($category);
                 }
             }
         }
     }
     // p2p connections
     $p2ps = $this->db->table('wp_p2p')->get();
     foreach ($p2ps as $p2p) {
         list($from, $t, $to) = explode('-', $p2p->p2p_type);
         switch ($from) {
             case 'activity':
                 $from = Activity::findWordpress($p2p->p2p_from)->first();
                 $from_table = 'activity';
                 break;
             case 'badge':
                 $from = Badge::findWordpress($p2p->p2p_from)->first();
                 $from_table = 'badge';
                 break;
             case 'dma-location':
                 $from = Location::findWordpress($p2p->p2p_from)->first();
                 $from_table = 'location';
                 break;
             case 'step':
                 $from = Step::findWordpress($p2p->p2p_from)->first();
                 $from_table = 'step';
                 break;
             default:
                 $from = false;
         }
         switch ($to) {
             case 'activity':
                 $to = Activity::findWordpress($p2p->p2p_to)->first();
                 $to_table = 'activity';
                 break;
             case 'badge':
                 $to = Badge::findWordpress($p2p->p2p_to)->first();
                 $to_table = 'badge';
                 break;
             case 'dma-location':
                 $to = Location::findWordpress($p2p->p2p_to)->first();
                 $to_table = 'location';
                 break;
             case 'step':
                 $to = Step::findWordpress($p2p->p2p_to)->first();
                 $to_table = 'step';
                 break;
             default:
                 $to = false;
         }
         if ($from && $to) {
             $table = 'dma_friends_' . $from_table . '_' . $to_table;
             switch ($table) {
                 case 'dma_friends_activity_step':
                     $from->steps()->save($to);
                     $this->info('activity: ' . $from->title . ' --> step: ' . $to->title);
                     break;
                 case 'dma_friends_step_badge':
                     $to->steps()->save($from);
                     $this->info('step: ' . $from->title . ' --> badge: ' . $to->title);
                     break;
                 default:
                     $values = [$from_table . '_id' => $from->id, $to_table . '_id' => $to->id];
                     if (Schema::hasTable($table)) {
                         DB::table($table)->insert($values);
                         $this->info('from: ' . $from->title . ' ----- ' . $to->title);
                     } else {
                         $this->error('table doesnt exist: ' . $table);
                     }
             }
         }
     }
     // User achievements
     $achievements = $this->db->table('wp_usermeta')->where('meta_key', '_badgeos_achievements')->get();
     $post = new Post();
     $this->info('Sync Achievements');
     foreach ($achievements as $achievement) {
         $user = User::find($achievement->user_id);
         if (empty($user)) {
             continue;
         }
         // Flush existing records
         DB::table($this->userStepTable)->where('user_id', $user->id)->delete();
         DB::table($this->userBadgeTable)->where('user_id', $user->id)->delete();
         $data = unserialize($achievement->meta_value);
         // wtf we don't need arrays in our arrays if we want to array
         $data = array_pop($data);
         foreach ($data as $d) {
             $link = ['user_id' => $user->id, 'created_at' => $post->epochToTimestamp($d->date_earned)];
             // About half way thru the data for the location key changes.
             // so lets deal with that
             if (isset($d->location)) {
                 $location_id = $d->location;
             } elseif (isset($d->location_earned)) {
                 $location_id = $d->location_earned;
             } else {
                 $location_id = null;
             }
             $location = Location::findWordpress($location_id)->first();
             if (isset($location->id)) {
                 $link['location_id'] = $location->id;
             }
             if ($d->post_type == 'step') {
                 $step = Step::findWordpress($d->ID)->first();
                 if ($step) {
                     $link['step_id'] = $step->id;
                     DB::table($this->userStepTable)->insert($link);
                 }
             } elseif ($d->post_type == 'badge') {
                 $badge = Badge::findWordpress($d->ID)->first();
                 if ($badge) {
                     $link['badge_id'] = $badge->id;
                     DB::table($this->userBadgeTable)->insert($link);
                 }
             }
         }
     }
     // Syncronize activities and users
     $this->info('Importing Activity/User relations');
     $table = 'dma_friends_activity_user';
     DB::table($table)->delete();
     ActivityLog::where('action', '=', 'activity')->chunk(100, function ($activityLogs) use($table) {
         foreach ($activityLogs as $activityLog) {
             if ($activityLog->object_id) {
                 echo '.';
                 $pivotTable = ['user_id' => $activityLog->user_id, 'activity_id' => $activityLog->object_id, 'created_at' => $activityLog->timestamp, 'updated_at' => $activityLog->timestamp];
                 DB::table($table)->insert($pivotTable);
             }
         }
     });
     // Syncronize rewards and users
     $this->info('Importing Reward/User relations');
     $table = 'dma_friends_reward_user';
     //DB::table($table)->delete();
     ActivityLog::where('action', '=', 'reward')->where('timestamp', '<', '2015-02-02 12:10:35')->chunk(100, function ($activityLogs) use($table) {
         foreach ($activityLogs as $activityLog) {
             if ($activityLog->object_id) {
                 echo '.';
                 if (Reward::find($activityLog->object_id) && User::find($activityLog->user_id)) {
                     $pivotTable = ['user_id' => $activityLog->user_id, 'reward_id' => $activityLog->object_id, 'created_at' => $activityLog->timestamp, 'updated_at' => $activityLog->timestamp];
                     DB::table($table)->insert($pivotTable);
                 }
             }
         }
     });
     $this->info('Sync complete');
 }
 /** 
  * Import user accounts from wordpress
  *
  * @param int $limit
  * The amount of records to import at one time
  */
 public function import($limit = 0)
 {
     $count = 0;
     $table = $this->model->table;
     $id = (int) DB::table($table)->max('id');
     $wordpressLogs = $this->db->table('wp_badgeos_logs')->where('id', '>', $id)->orderBy('id', 'asc')->limit($limit)->get();
     // Use dummy model to get action types
     $l = new $this->model();
     foreach ($wordpressLogs as $wlog) {
         if (!in_array($wlog->action, $l->actionTypes)) {
             continue;
         }
         $object = false;
         $log = new $this->model();
         $log->id = $wlog->id;
         $log->user_id = $wlog->user_id;
         $log->action = $wlog->action;
         $log->message = $wlog->message;
         $log->points_earned = $wlog->points_earned;
         $log->total_points = $wlog->total_points;
         $log->timestamp = $wlog->timestamp;
         $log->timezone = $wlog->timezone;
         if ($wlog->action == 'artwork') {
             $log->artwork_id = $wlog->object_id;
             $object = OctoberActivity::where('activity_type', '=', 'LikeWorkOfArt')->first();
         } else {
             // Get the wordpress post type
             $post_type = $this->db->table('wp_posts')->select('post_type')->where('ID', $wlog->object_id)->first();
             if (isset($post_type->post_type)) {
                 // Convert the post type to a usable object model
                 switch ($post_type->post_type) {
                     case 'activity':
                         $object = OctoberActivity::findWordpress($wlog->object_id);
                         break;
                     case 'badge':
                         $object = OctoberBadge::findWordpress($wlog->object_id);
                         break;
                     case 'badgeos-rewards':
                         $object = OctoberReward::findWordpress($wlog->object_id);
                         break;
                     case 'dma-location':
                         $object = OctoberLocation::findWordpress($wlog->object_id);
                         break;
                     case 'step':
                         $object = OctoberStep::findWordpress($wlog->object_id);
                         break;
                     default:
                         continue;
                 }
             } else {
                 continue;
             }
         }
         try {
             if ($log->save()) {
                 // If the log is related to an object, save that relation
                 if ($object) {
                     $object = $object->first();
                     // Ugly hack to get sync working for now
                     if (get_class($object) == 'DMA\\Friends\\Wordpress\\ActivityLog') {
                         continue;
                     }
                     $object->activityLogs()->save($log);
                 }
                 $count++;
             }
         } catch (Exception $e) {
             echo "Failed to import log entry id: " . $log->id . "\n";
             echo $e->getMessage() . "\n";
         }
     }
     return $count;
 }
 /**
  * Query scope to filter activity metadata by the given key and value
  * @param mixed $query
  * @param RainLab\User\Models\User $user
  * @param DMA\Friends\Models\Activity $activity
  * @param string $key
  * @param string $value
  */
 public function scopeHasMetadataValue($query, $user, $activity, $key, $value)
 {
     return self::where('user_id', $user->getKey())->where('activity_id', $activity->getKey())->where('key', $key)->where('value', $value);
 }