Giter Club home page Giter Club logo

laravel-achievements's People

Contributors

alexgodbehere avatar butschster avatar gabs-simon avatar silverqx avatar wall-e-psr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

laravel-achievements's Issues

Achievement description

Hi again,

I've seen there is only a $description property which seems, according to the examples, to be used to display a message to the user when they reach the achievement.
This is misleading, IMHO, since the description should describe (sic) the achievement and, therefore, be displayed in the list of achievements, so that users know what they have to do to reach the achievement.
The $description should then describe the achievement, and a $message property should be displayed when the user unlocks the achievement.

Since the property is public, we can obviously add another property to achieve this. But the examples in the documentation are not very explicit about the contexts.

Also, since the package is designed for Laravel, what about adding localization? Rather than using description property, we could have a getDescription() method which would return the description translated (or not, depending on configuration). Also, a getMessage() method would display the message.
A getter would allow developer to add some logic before returning the message/description (maybe you want to return the text with a different vocabulary, for example for adults or children users).

I'd be happy to submit proposals and PRs after discussing this.

Past Timestamps / Pass a Timestamp

Is there a way to pass a timestamp to the achievements? I'm trying to add achievements to an existing site and would like to pass a timestamp, so the achievements are recorded as being earned when the old activity happened.

Add Achievements (SUGGESTION)

Is there a way down the road to make logic/frontend so one can create/edit achievements on the fly which could be integrated into a existing admin panel or something. That way staff of site could add new Achievements from site and not have to use terminal and edit code in like sublime text?

I know this is long shot and probably not easy todo with how the Achievements system works now but thought i would throw the idea out there as it would make it more user friendly.

Achievement Categories

Make it so Achievements can be categorized.
Create methods to show only achievements of a specific category.

Locking

I am looking for a way to lock achievement. Is is possible?

Laravel 6 support?

@gabriel-simonetti
Thanks for this awesome library.

Any hope for Laravel 6 support? Thanks

Inefficient use of database

I saw that achievement generation is quite inefficient when it comes to database usage.
The culprit is getModel method that is called 3 times for each achievement progress modification:

  • in constructor
  • in getOrCreateProgressForAchiever to fetch achievement id
  • in getOrCreateProgressForAchiever to associate newly created progress with details model

Then in this getModel method we have 2 database calls: read and save
That makes 6 database calls (8 if there is an update) for each achievement update.

My suggestion would be to make a dedicated command for synchronizing achievement details with database and remove save call from getModel as well as getModel call from constructor (possibly as a config option for backword compatibility) .

An extra improvement would be to reuse results of getModel instead of calling it each time.

Another suggestion would be to add an option for having stable ids
(eg. calculated from md5 of achievement fully qualified class name or just provided by user)
and assume that those will match model's id,
but that is something to be discussed
and since its a super breaking change, definitely require a config option.

Implement onUnlock handler based on Laravel event system

Currently, the Achievements have an undocumented (and untested) functionality: They can implement a onUnlock method, receiving an instance of AchievementProgress, that will be called whenever this specific Achievement is unlocked.

This is a bad idea because it does not implement default Laravel conventions. This should be replaced with an implementation that calls Laravel Events.

Achievement Chain

Sometimes, there are multiple achievements that track the exact same thing, but with different points to obtain.

For example, an user can obtain a "Newcomer" achievement when creating their first comment on the site, a "Regular Commenter" achievement when they reached 10 comments and a "Regular Commenter" achievement when they reached 100 comments.

Currently, these achievements need to be tracked separately, something like this:

<?php
use App\Achievements\Newcomer;
use App\Achievements\RegularCommenter;
use App\Achievements\VeteranCommenter;

public function createComment($user, $comment){
     // Some logic to be processed when the user creates a comment...
    $user->addProgress(Newcomer, 1);
    $user->addProgress(RegularCommenter, 1);
    $user->addProgress(VeteranCommenter, 1);
}

And this would quickly grow out of hand when there are many achievements tracking the same thing. In order to solve this problem, I propose a feature called "Achievement Chain". It would work in the following way:

  1. A new abstract class, AchievementChain will be created. This class will be defined only by a list of achievements.
  2. All methods that can be used to add, remove, set reset progress to Achievements can also receive instances of AchievementChain. When one of this methods receive an instance of AchievementChain, it will call the same method for every Achievement described in the definition of the AchievementChain instance.

[Question] Cron Job for achivement progress?

Several Achievements use some DB data for their progress, how can I update the point progress of the achievements?

I was thinking on a cron job every X time that checks the DB and sets the progress. How can I implement something like that in Laravel?

Thank you, great job!

Unit Testing and Travis CI

In order to create stable releases, laravel-achievements will require testing and continuous integration.
A simple way to achieve that is to implement PHPUnit tests and Travis CI.

Multilanguage Achiefment

How do i make the achiefment multilanguage? I see the achiefment as somethign that is saved in the database, but how do i translate this achiefment?

Locked Achievements (SUGGESTION)

A way to display a list of all achievements that are locked so users can see what they have yet to accomplish.

something like so:
http://imgur.com/tJf5DQE

Progress for Locked Achievements would always be Locked by Default. As once its not locked its removed from locked list and added to Completed Achievements list

Documentation Improvement

Hello to all users of the laravel-achievements package!

I'm currently writing a new version of the documentation and would like to hear feedback from everyone.

Please consider leaving a comment letting me know about:

  • How did you like the current README.md file? Is it clear? Is it beginner-friendly?
  • Did you experience any problems while using this package that the documentation wasn't clear enough?
  • How did you like the examples provided in the current documentation?
  • Do you have anything else to add?

Thank you very much!

Reset Specific Achievement

I'm wondering if there is a way to edit an item in the achievement_progress table specifically? The problem that I have is that I need to reset the number of points back down to 0 if a user gets something wrong in whatever unlocked achievement they currently are working on.

If I just go into the DB table itself and edit the specific row with the code below, I'm able to reset the points, but it also loads every single achievement into the achievement_progress table for the user, and I don't want to clutter this table up with achievements that aren't valid for some time.

        $progress = $this->inProgressAchievements()->first();
        if($progress) {
            $progress->points = 0;
            $progress->save()
        }

This sends all possible achievements to the achievement_progress table, even though it does reset the achievement in progress.

[REQUEST] Improve returned data

When doing a query for user achievements and unlocked ones, the returned data is not pretty optimized. (Personal point of view).

Example of $user->unlockedAchievements()->all():

Array ( [0] => Gstt\Achievements\Model\AchievementProgress Object ( [incrementing] => [table:protected] => achievement_progress [guarded:protected] => Array ( ) [casts:protected] => Array ( [unlocked_at] => datetime ) [connection:protected] => mysql [primaryKey:protected] => id [keyType:protected] => int [with:protected] => Array ( ) [withCount:protected] => Array ( ) [perPage:protected] => 15 [exists] => 1 [wasRecentlyCreated] => [attributes:protected] => Array ( [id] => 77352394-32ec-4122-a970-dc2614ae51f6 [achievement_id] => 4 [achiever_id] => 1 [achiever_type] => App\User [points] => 0 [unlocked_at] => 2018-02-21 19:02:54 [created_at] => 2018-03-02 13:32:00 [updated_at] => 2018-03-02 13:32:00 ) [original:protected] => Array ( [id] => 77352394-32ec-4122-a970-dc2614ae51f6 [achievement_id] => 4 [achiever_id] => 1 [achiever_type] => App\User [points] => 0 [unlocked_at] => 2018-02-21 19:02:54 [created_at] => 2018-03-02 13:32:00 [updated_at] => 2018-03-02 13:32:00 ) [changes:protected] => Array ( ) [dates:protected] => Array ( ) [dateFormat:protected] => [appends:protected] => Array ( ) [dispatchesEvents:protected] => Array ( ) [observables:protected] => Array ( ) [relations:protected] => Array ( ) [touches:protected] => Array ( ) [timestamps] => 1 [hidden:protected] => Array ( ) [visible:protected] => Array ( ) [fillable:protected] => Array ( ) ) [1] => Gstt\Achievements\Model\AchievementProgress Object ( [incrementing] => [table:protected] => achievement_progress [guarded:protected] => Array ( ) [casts:protected] => Array ( [unlocked_at] => datetime ) [connection:protected] => mysql [primaryKey:protected] => id [keyType:protected] => int [with:protected] => Array ( ) [withCount:protected] => Array ( ) [perPage:protected] => 15 [exists] => 1 [wasRecentlyCreated] => [attributes:protected] => Array ( [id] => 95d4e3c1-64f2-4649-be50-fa81d90e98fc [achievement_id] => 1 [achiever_id] => 1 [achiever_type] => App\User [points] => 1 [unlocked_at] => 2018-02-21 19:02:54 [created_at] => 2018-02-21 19:02:54 [updated_at] => 2018-02-21 19:02:54 ) [original:protected] => Array ( [id] => 95d4e3c1-64f2-4649-be50-fa81d90e98fc [achievement_id] => 1 [achiever_id] => 1 [achiever_type] => App\User [points] => 1 [unlocked_at] => 2018-02-21 19:02:54 [created_at] => 2018-02-21 19:02:54 [updated_at] => 2018-02-21 19:02:54 ) [changes:protected] => Array ( ) [dates:protected] => Array ( ) [dateFormat:protected] => [appends:protected] => Array ( ) [dispatchesEvents:protected] => Array ( ) [observables:protected] => Array ( ) [relations:protected] => Array ( ) [touches:protected] => Array ( ) [timestamps] => 1 [hidden:protected] => Array ( ) [visible:protected] => Array ( ) [fillable:protected] => Array ( ) ) )

Is really all that data necessary for just 2 achievements? Could be refactored on simpler and more usefull way?

Multiple Models as Achiever

I have two models that I'd like to earn achievements on, is that possible? I'm getting unexpected behavior.

ModelOne

use Gstt\Achievements\Achiever;
use Illuminate\Database\Eloquent\Model;

class ModelOne extends Model
{
    use Achiever;
}

ModelTwo

use Gstt\Achievements\Achiever;
use Illuminate\Database\Eloquent\Model;

class ModelTwo extends Model
{
    use Achiever;
}

Achievements are working as expected for ModelOne, but ModelTwo is not. This, for example, is getting wrongly saved as being ModelOne...

$model = ModelTwo::first();
$model->unlockIfLocked(new ThisAchievement());

And the achievements relationship is screwy, as well. App\ModelTwo::has('achievements')->first() does this...


Illuminate/Database/QueryException with message 'SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'achiever_id' cannot be null (SQL: insert into `achievement_progress` (`achievement_id`, `achiever_id`, `achiever_type`, `points`, `id`, `updated_at`, `created_at`) values (1, , App/ModelTwo, 0, d319c898-482c-4833-bc3d-a2c588ba1545, 2018-08-23 12:13:28, 2018-08-23 12:13:28))'

It's possible that it's related to my custom trait that I made:

namespace App\Traits;

use Gstt\Achievements\Achievement;

trait Achievable
{
    /**
     * Unlock If Locked
     * 
     * @param Achievement $achievement
     * @return void
     */
    public function unlockIfLocked(Achievement $achievement)
    {
        if(! $this->hasUnlocked($achievement))
        {
            $this->unlock($achievement);
        }
    }
}

how to unlock the achievement within a month

Currently i am working on new project and i have to create Made 20 appointments in one month achievement. So how can i set the unlocked_at field in achievement_progress table of one month timestamp from current date of making an appointment

Class 'Gstt\Achievements\AchievementsServiceProvider' not found

Hi,

when i run composer update i got the following error:

  [Symfony\Component\Debug\Exception\FatalThrowableError]
  Class 'Gstt\Achievements\AchievementsServiceProvider' not found

Script php artisan optimize handling the post-update-cmd event returned with error code 1

composer.json
...
"gstt/laravel-achievements": "^0.0.3",
...

config/app.php
...
Gstt\Achievements\AchievementsServiceProvider::class,
...

Laravel Framework 5.4.15

Looks like php artisan optimize crashed

Choose which database the tables reside in

Is there a way to configure the used database for the achievements (details and progress)?

I use a system containing multiple databases, and the achievement tables should not necessarily reside in the default database.

I got a working version by directly editing the source code, but this would not be future proof, as newer versions would just overwrite it.

Gamerscore implementation

Gamerscore is a feature used on Xbox Live tied to the Achievement System.

Achievers are rewarded with a specified amount of points (usually a number between 5 and 100 which reflects how hard the achievement is to obtain) whenever they unlock an Achievement. The score is added to the Achiever's Gamerscore, defined as a sum of all points obtained upon unlocking Achievements.

Achievement and permission

Hi,

I'm about using this package in a new project and I have one suggestion: what about granting permissions when some achievements are reached?
For example, on StackOverflow, you need to have at least 125 reputation to downvote, or 1500 to create tags.
I guess it's rather easy to set it up with a policy, but maybe it could be made with the achievements api?

Samples Views/Controller?

Possible to add some samples that will work with this package out the box so noobs like me have a base starting point?

getOrCreateProgressForAchiever ignores achiever?

Problem:
Only for user A a database record was created in the "achievement_progress" table.

$progress = AchievementProgress::where('achiever_type', $className)
->where('achievement_id', $achievementId)
->where('achiever_id', $achiever->id) // i think you forgot this line?
->first();

Unlock/Progress Events

Hello. How am I able to use sweetalert2 for these events?I would like a popup like this when progress or a unlock is made.

https://codepen.io/anon/pen/yXXGPy

Is this possible and if not what to you recommend for alerts? I use toastr for my sites alerts but wanted something little pronounced for achievement alerts.

Thanks.

Command "make:achievement" is not defined.

Hi, I have recently installed the package, I when I tried to run the following command, the terminal return mi the next error:
domain@hl361:~/www$ php artisan make:achievement UserMadeAPost
Command "make:achievement" is not defined.
Did you mean one of these?
make:auth
make:chart
make:command
make:controller
make:event
make:exception
make:factory
make:job
make:listener
make:mail
make:middleware
make:migration
make:model
make:notification
make:policy
make:provider
make:request
make:resource
make:rule
make:seeder
make:test

uuid on progress_details table

Hi

Im trying to understand why the id of table achievement_progress uses a unique identifier:

Uuid::uuid4()->toString();

Wouldnt a regular incremented integer suffice?

Thanks

Unlocked Achievements Count (SUGGESTION)

built in unlocked Achievements counter so can be easily displayed in master/default view. Maybe like so:

<?php $count = Auth::user()->unlockedAchievementsCount(); ?>

with will in return display the count of all the unlocked Achievements that user has?

Support

Hi Gabriel,
is there another way to get in contact with you?
BR
Jerry

Images

Is there an expected or suggested way to include images to represent the badges? My solution at present is basically

<img src="{{ asset('img/badges/'.str_replace(' ', '_', $achievement->details->name). '.png') }}">

But maybe there's a better way? If so, it seems worth mentioning it in the docs, or maybe including a few different examples of tactics for associating images with your badges. :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.