The Right Toolbox

The Right Toolbox

Choosing the right tool for the job sometimes means bringing along a whole toolbox. I’ll show how a complex back-end system was built with Craft, Laravel, Redis, and more, all working in harmony.

4b9a52ce862b15437f17695c02c61467?s=128

Anthony Colangelo

April 24, 2014
Tweet

Transcript

  1. https://www.flickr.com/photos/iangbl/

  2. https://www.flickr.com/photos/florianric/

  3. https://www.flickr.com/photos/pennuja/

  4. Yeah, we could make that work.

  5. Yeah, we could make that work. But…

  6. None
  7. None
  8. None
  9. None
  10. None
  11. None
  12. Content

  13. Content Users

  14. Content Users Voting

  15. https://www.flickr.com/photos/beraldoleal

  16. None
  17. Route::get('/', array( 'as' => 'home', 'uses' => 'HomeController@ ', 'after'

    => 'cache' )); showVoteHome
  18. ! ! Route::filter('cache', function($route, $request, $response, $max_age=1200) { });

  19. class Nominee extends Eloquent { ! // ... ! }

  20. None
  21. Content

  22. None
  23. None
  24. None
  25. SELECT description, body, tagline, hashtag, closingTime FROM craft_content

  26. None
  27. None
  28. None
  29. None
  30. None
  31. None
  32. // ... } class Nominee extends Eloquent {

  33. // ... } class Nominee extends Eloquent { protected $table

    = 'craft_entries_i18n';
  34. // ... } class Nominee extends Eloquent { protected $table

    = 'craft_entries_i18n'; private $sectionId = 2;
  35. public function scopeListing($query) { return $query ->select( /* ... */

    ) ->join( /* ... */ ) ->where( /* ... */ ); }
  36. public function scopeListing($query) { return $query ->select( /* ... */

    ) ->join('craft_content', 'craft_content.elementId', '=', 'craft_entries_i18n.entryId') ->join('craft_entries', 'craft_entries.id', '=', 'craft_entries_i18n.entryId') ->join('craft_elements', 'craft_elements.id', '=', 'craft_entries_i18n.entryId') ->where('craft_entries_i18n.sectionId','=',$this->sectionId) ->where('craft_entries.postDate','<=',date_format(new DateTime(),'Y-m-d G:i:s')) ->where(function($query) { $query ->where('craft_entries.expiryDate','=',NULL) ->orWhere('craft_entries.expiryDate','>=',date_format(new DateTime(),'Y-m-d G:i:s')); }) ->where('craft_elements.enabled','=',1); }
  37. ->where( 'craft_entries_i18n.sectionId','=', $this->sectionId )

  38. ->join('craft_content', 'craft_content.elementId', '=', 'craft_entries_i18n.entryId' )

  39. ->join('craft_entries', 'craft_entries.id', '=', 'craft_entries_i18n.entryId' )

  40. ->where('craft_entries.postDate','<=', date_format(new DateTime(),'Y-m-d G:i:s') )

  41. ->where(function($query) { $query ->where('craft_entries.expiryDate','=',NULL) ->orWhere('craft_entries.expiryDate','>=', date_format(new DateTime(),'Y-m-d G:i:s')); })

  42. ->join('craft_elements', 'craft_elements.id', '=', 'craft_entries_i18n.entryId' )

  43. ->where('craft_elements.enabled','=',1)

  44. public function scopeListing($query) { return $query ->select( /* ... */

    ) ->join( /* ... */ ) ->where( /* ... */ ); }
  45. $nominees = Nominee::listing() ->orderBy('craft_entries_i18n.title') ->get();

  46. None
  47. Users

  48. None
  49. None
  50. None
  51. None
  52. None
  53. None
  54. None
  55. // ... } class User extends Eloquent {

  56. // ... } class User extends Eloquent { protected $table

    = 'craft_users';
  57. craft_users id username firstName lastName status

  58. oma_users userId avatar bio providerData providerTokens craft_users id username firstName

    lastName status
  59. None
  60. None
  61. None
  62. None
  63. Voting

  64. None
  65. public function cast($voterId, $nomineeId, $categoryId, $influencerId = 0) { !

    // ... ! }
  66. $redis = Redis::connection('oma4-votes'); ! $voter = "user[{$voterId}]"; $nominee = "nominee[{$nomineeId}]";

    $category = "category[{$categoryId}]"; $influencer = “user[{$influencerId}]”; ! $datetime = new DateTime(); $date['day'] = $datetime->format('Y-m-d'); $date['hour'] = $datetime->format('Y-m-d-H');
  67. // Vote Counts $redis->incrby('votes',1); $redis->hincrby("votes:{$voter}",'total',1); $redis->hincrby("votes:{$voter}",'cast',1);

  68. // Nominee Standings $redis->zincrby("standings:nominee",1,$nominee); $redis->zincrby("standings:nominee:{$category}",1,$nominee); $redis->zincrby("standings:nominee:{$voter}",1,$nominee);

  69. $redis->zrevrange( "standings:nominee", 0, -1, 'WITHSCORES' );

  70. // Activity Trends $redis->hincrby("trends:{$voter}",$date['day'],1); $redis->hincrby("trends:{$voter}",$date['hour'],1); $redis->hincrby("trends:{$nominee}",$date['hour'],1); $redis->hincrby("trends:{$category}",$date['hour'],1);

  71. $hourOne = $redis->hget("trends:{$nominee}", '2013-06-19-20'); $hourTwo = $redis->hget("trends:{$nominee}", '2013-06-19-21'); $hourThree =

    $redis->hget("trends:{$nominee}", '2013-06-19-22');
  72. None
  73. None
  74. None
  75. None
  76. None
  77. None
  78. Be Pragmatic.

  79. @acolangelo