Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make looking for badges directory recursive. #24

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,24 @@ $user->undoPoint(new PostCreated($post));
$post->delete();
```

You can also pass second argument as $user in helper function `givePoint(new PostCreated($post, $user))`, default is auth()->user().
You can also pass second argument as $user in helper function `givePoint(new PostCreated($post) $user)`, default is auth()->user().

**Pro Tip 👌** You could also hook into the Eloquent model event and give point on `created` event. Similarly, `deleted` event can be used to undo the point.

### Give or update points to User

There may be a situation where the points given for a reputation record changes over time. For example, a comment to a post that can be up voted. Those votes are given to the commenter as they come in.

For this situation you can use the `giveOrUpdatePoint` helper which will give the points or update them automatically to the user's reputation total

``` php
// create initial reputation record with 5 points
giveOrUpdatePoint(new PostCommentVotes($postComment, 5), $user);

// update reputation record to 20 points for the same $postComment db record
giveOrUpdatePoint(new PostCommentVotes($postComment, 20), $user);
```

### Get total reputation

To get the total user reputation you have `$user->getPoints($formatted = false)` method available. Optioally you can pass `$formatted = true` to get reputation as 1K+, 2K+ etc.
Expand Down
34 changes: 30 additions & 4 deletions src/GamifyServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
use QCod\Gamify\Console\MakePointCommand;
use QCod\Gamify\Events\ReputationChanged;

use \RecursiveDirectoryIterator;
use \RecursiveIteratorIterator;
use \RecursiveRegexIterator;
use \RegexIterator;

class GamifyServiceProvider extends ServiceProvider
{
/**
Expand Down Expand Up @@ -77,10 +82,31 @@ protected function getBadges()

$badges = [];

foreach (glob(app_path('/Gamify/Badges/') . '*.php') as $file) {
if (is_file($file)) {
$badges[] = app($badgeRootNamespace . '\\' . pathinfo($file, PATHINFO_FILENAME));
}
// Get the first folder for the app. For the vast majority of all projects this is "App"
$rootFolder = substr($badgeRootNamespace, 0, strpos($badgeRootNamespace, '\\'));

// Create recursive searching classes
$directory = new RecursiveDirectoryIterator(app_path('Gamify/Badges/'));
$iterator = new RecursiveIteratorIterator($directory);
$files = new RegexIterator($iterator, '/^.+\.php$/i', RecursiveRegexIterator::GET_MATCH);

// loop through each file found
foreach ($files as $file) {

// grab the directory for the file
$fileDirectory = pathinfo($file[0], PATHINFO_DIRNAME);

//remove full server path and prepend the rootfolder
$fileDirectory = $rootFolder.str_ireplace(app_path(), '', $fileDirectory);

// convert the forward slashes to backslashes
$fileDirectory = str_ireplace('/', '\\', $fileDirectory);

// get the file name
$fileName = pathinfo($file[0], PATHINFO_FILENAME);

//append namespace file path to the badges array to return
$badges[] = $fileDirectory."\\".$fileName;
}

return collect($badges);
Expand Down
36 changes: 36 additions & 0 deletions src/HasReputations.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,26 @@ public function givePoint(PointType $pointType)
}
}

/**
* Give or update reputation points to payee
*
* @param PointType $pointType
* @return bool
*/
public function giveOrUpdatePoint(PointType $pointType)
{
if (!$pointType->qualifier()) {
return false;
}

if ($pointType->reputationExists()) {
$originalPoints = $pointType->syncPointsChange();
return $pointType->payee()->syncPointsChange($originalPoints, $pointType->getPoints());
}else if ($this->storeReputation($pointType)) {
return $pointType->payee()->addPoint($pointType->getPoints());
}
}

/**
* Undo last given point for a subject model
*
Expand Down Expand Up @@ -82,6 +102,22 @@ public function addPoint($point = 1)
return $this;
}

/**
* Sync points changed for a reputation record to a payee
*
* @param int $point
* @return HasReputations|\Illuminate\Database\Eloquent\Model
*/
public function syncPointsChange($originalPoints, $newPoints = 1)
{
$this->decrement($this->getReputationField(), $originalPoints);
$this->increment($this->getReputationField(), $newPoints);

ReputationChanged::dispatch($this, $newPoints, true);

return $this;
}

/**
* Reduce a user point
*
Expand Down
14 changes: 14 additions & 0 deletions src/PointType.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,20 @@ public function storeReputation($meta = [])
]);
}

/**
* Sync updates to points to an existing reputation record
* @return int $originalPoints
*/
public function syncPointsChange()
{
$dbPointType = $this->firstReputation();
$originalPoints = $dbPointType->point;
$dbPointType->update([
'point' => $this->getPoints()
]);
return $originalPoints;
}

/**
* Get reputation query for this point
*
Expand Down
20 changes: 20 additions & 0 deletions src/helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,26 @@ function givePoint(PointType $pointType, $payee = null)
}
}

if (!function_exists('giveOrUpdatePoint')) {

/**
* Give point to user
*
* @param PointType $pointType
* @param null $payee
*/
function giveOrUpdatePoint(PointType $pointType, $payee = null)
{
$payee = $payee ?? auth()->user();

if (!$payee) {
return;
}

$payee->giveOrUpdatePoint($pointType);
}
}

if (!function_exists('undoPoint')) {

/**
Expand Down
53 changes: 53 additions & 0 deletions tests/PointTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,41 @@ public function it_gives_point_to_a_user()
]);
}

/**
* it gives point to a user, then updates it validating that that change
*
* @test
*/
public function it_gives_and_updates_points_to_a_user()
{
$user = $this->createUser();
$post = $this->createPost(['user_id' => $user->id]);

$user->giveOrUpdatePoint(new FakeUpdateablePostPoint($post));

$this->assertEquals(1, $user->fresh()->getPoints());
$this->assertCount(1, $user->reputations);
$this->assertDatabaseHas('reputations', [
'payee_id' => $user->id,
'subject_type' => $post->getMorphClass(),
'subject_id' => $post->id,
'point' => 1,
'name' => 'FakeUpdateablePostPoint'
]);

$user->giveOrUpdatePoint(new FakeUpdateablePostPoint($post, 5));

$this->assertEquals(5, $user->fresh()->getPoints());
$this->assertCount(1, $user->reputations);
$this->assertDatabaseHas('reputations', [
'payee_id' => $user->id,
'subject_type' => $post->getMorphClass(),
'subject_id' => $post->id,
'point' => 5,
'name' => 'FakeUpdateablePostPoint'
]);
}

/**
* it can access a reputation payee and subject
*
Expand Down Expand Up @@ -269,6 +304,24 @@ public function payee()
}
}

class FakeUpdateablePostPoint extends PointType
{
protected $points = 1;

public $allowDuplicates = false;

public function __construct($subject, $points = 1)
{
$this->subject = $subject;
$this->points = $points;
}

public function payee()
{
return $this->getSubject()->user;
}
}

class FakeWelcomeUserWithNamePoint extends PointType
{
protected $name = 'FakeName';
Expand Down