Skip to content

Instantly share code, notes, and snippets.

@patrickisgreat
Created August 10, 2016 15:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save patrickisgreat/a533a779dd1d2c01e76d58b06d3fc833 to your computer and use it in GitHub Desktop.
Save patrickisgreat/a533a779dd1d2c01e76d58b06d3fc833 to your computer and use it in GitHub Desktop.
Example Implementation of Baum/Node in Laravel Spark App
<?php
namespace App\Http\Controllers\API;
use App\Repositories\CategoryRepository;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Permission;
use App\Category;
use Debugbar;
use App\Role;
use App\User;
use App\Team;
use Auth;
use Log;
class CategoryController extends ResourceController
{
public function __construct(Request $request, Category $model)
{
$this->request = $request;
$this->resource = $model;
$this->user = Auth::user();
}
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index($teamId = null)
{
return CategoryRepository::getTree($teamId);
}
}
<?php
namespace App\Repositories;
use App\Contracts\Repositories\CategoryRepositoryContract as CategoryContract;
use Illuminate\Database\Eloquent\Collection;
use App\Category;
use App\Team;
use Cache;
use Auth;
class CategoryRepository implements CategoryContract {
/**
* @var Repository
*/
protected $cache;
public $category;
/**
* @param Repository $cache
* @param Category $category
*/
public function __construct(Cache $cache, Category $category)
{
$this->cache = $cache;
$this->category = $category;
}
/**
* Get the category matching this id, depth, and team.
*
* @param string|int $id
* @return \Illuminate\Database\Eloquent\Collection
*/
public static function find($name, $depth, $team_id) {
return Category::where('name', '=', $name)->where('depth', '=', $depth)->where('team_id', '=', $team_id)->first();
}
/**
* Get the entire tree as a collection.
*
* @return \Illuminate\Database\Eloquent\Collection
*/
public static function all() {
return Category::all();
}
/**
* Get the root category
*
* @param string|int $name
* @param int $depth
* @param int $team_id
*
* @return \Illuminate\Database\Eloquent\Collection
*/
public static function findRoot($name, $depth, $team_id) {
}
/**
* Get all of the categories for a given Team
*
* @param \App\Team $team
* @return \Illuminate\Database\Eloquent\Collection
*/
public static function teamCategories($team) {
}
/**
* Save a new Category
*
* @param \App\Team $team
* @param array $data
* @return Team
*/
public function save($name, $depth, $teamId) {
$cacheKey = 'vacoda.category.'.$depth;
if ($depth === 0) {
$root = $this->category->create(['name' => $name, 'team_id' => $teamId]);
$root->save();
return Cache::forever($cacheKey, $root->name);
}
if ($depth > 0) {
$lastDepth = (string) $depth - 1;
$last_cached_category_key = 'vacoda.category.'.$lastDepth;
$last_cached_category_name = Cache::get($last_cached_category_key);
$last_cached_category = static::find($last_cached_category_name, $lastDepth, $teamId);
$new_child_category = $last_cached_category->children()->create(['name' => $name, 'team_id' => $teamId]);
$new_child_category->save();
$store_current_category_in_cache = Cache::forever($cacheKey, $new_child_category->name);
return $new_child_category;
}
return response()->json(['error' => 'something is wrong in save method']);
}
/**
* @param $teamId
* @param $nodes
* @return mixed
*/
public static function filterByTeam($teamId, $nodes) {
$filtered_categories = $nodes->filter(function ($category) use ($teamId){
if ($category->team_id == $teamId) {
return $category;
}
});
return $filtered_categories;
}
/**
* Get All Roots
*
* @return Collection
*/
public static function getRoots($teamId) {
$category_roots = Category::roots()->get();
return self::filterByTeam($teamId, $category_roots);
}
/**
* Get the entire Tree
* @param int $teamId
* @return \Illuminate\Database\Eloquent\Collection
*/
public static function getTree($teamId) {
$roots = self::getRoots($teamId);
$tree = $roots->map( function($category) {
return $category->getDescendantsAndSelf()->toHierarchy();
});
return $tree;
}
}
<?php
namespace App\Contracts\Repositories;
use App\Team;
interface CategoryRepositoryContract
{
/**
* Get the category matching this id.
*
* @param string $name
* @param int @depth
* @param int @team_id
* @return \Illuminate\Database\Eloquent\Collection
*/
public static function find($name, $depth, $team_id);
/**
* Get the entire tree as a collection.
*
*
* @return \Illuminate\Database\Eloquent\Collection
*/
public static function all();
/**
* Get all of the categories for a given Team
*
* @param \App\Team $team
* @return \Illuminate\Database\Eloquent\Collection
*/
public static function teamCategories($team);
/**
* Create a new category on a given team
*
* @param \App\Team $team
* @param array $data
* @return Team
*/
public function save($name, $depth, $team_id);
/**
* Get the roots for all categories
*
* @param int $teamId
* @return \Illuminate\Database\Eloquent\Collection
*/
public static function getRoots($teamId);
/**
* Get the entire Tree
* @param int $teamId
* @return \Illuminate\Database\Eloquent\Collection
*/
public static function getTree($teamId);
}
<?php
namespace App\Http\Controllers;
use App\Repositories\CategoryRepository;
use Illuminate\Foundation\Application;
use App\Http\Controllers\Controller;
use Illuminate\Cache\Repository;
use App\Jobs\ImportCategoriesJob;
use Maatwebsite\Excel\Excel;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Category;
use App\Option;
use Exception;
use Validator;
use App\Offer;
use App\Team;
use Log;
class FileUploadController extends Controller
{
/**
* @var string
*/
protected $destinationPath;
/**
* @var Repository
*/
protected $cache;
/**
* @var CategoryRepository
*/
public $categoryRepo;
public $teamId;
public $spreadsheet_rows;
/**
* FileUploadController constructor.
* @param Repository $cache
* @param CategoryRepository $categoryRepository
*/
function __construct(CategoryRepository $categoryRepo)
{
$this->destinationPath = 'storage/tmp';
$this->categoryRepo = $categoryRepo;
}
/**
* Push the import onto the Beanstalk Queue
*
* @param Request $request
* @param Application $app
* @param Excel $excel
* @return Exception|mixed
*/
public function dispatchImport(Request $request, Application $app, Excel $excel) {
try {
$teamId = $request->user()->currentTeam->id;
$fileName = 'tempcategories.xls';
$request->file('spreadsheet')->move($this->destinationPath, $fileName);
$import_controller_instance = new SpreadsheetImportController($app, $excel);
$spreadsheet_rows = $import_controller_instance->get();
$this->dispatch(new ImportCategoriesJob($teamId, $spreadsheet_rows));
return back();
} catch (Exception $e) {
Log::info($e);
return $e;
}
}
/**
* Create the nested set
*
* @param $teamId
* @param $all_rows_from_spreadsheet
* @return Exception
*/
public function createImportedCategories($teamId, $all_rows_from_spreadsheet) {
$all_rows_from_spreadsheet = collect($all_rows_from_spreadsheet);
$categoryRepo = $this->categoryRepo;
try {
$all_rows_from_spreadsheet->each( function($row_of_categories) use ($teamId, $categoryRepo) {
$row_of_categories->each( function($category, $level) use ($teamId, $row_of_categories, $categoryRepo) {
$row_of_categories = $row_of_categories->toArray();
$depth = array_search($level, array_keys((array) $row_of_categories));
$does_this_category_already_exist = CategoryRepository::find($category, $depth, $teamId);
if ($category && $does_this_category_already_exist == null) {
return ${"category" . $level} = $categoryRepo->save($category, $depth, $teamId);
}
});
});
} catch (Exception $e) {
return $e;
}
}
/**
* @param SpreadsheetImportController $import
* @param Request $request
* @return \Illuminate\Http\RedirectResponse
*/
public function importSpreadsheet(SpreadsheetImportController $import, Request $request)
{
$results = $import->get()->toArray();
$TeamUrlName = $request->TeamUrlName;
foreach ($results as $result) {
$Team = Team::where('urlName', $TeamUrlName)->firstOrFail();
$department = Option::where('abbreviation', $result['department'])->firstOrFail();
$offers = new Offer();
$offers->Team_id = $Team->id;
$offers->department_id = $department->id;
$offers->fill($result);
$offers->save();
}
return redirect()->back();
}
}
<?php
namespace App\Jobs;
use Symfony\Component\HttpFoundation\File\File;
use App\Http\Controllers\FileUploadController;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Jobs\Job;
class ImportCategoriesJob extends Job implements ShouldQueue
{
use InteractsWithQueue, SerializesModels;
public $teamId;
public $spreadsheet_rows;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct($teamId, $spreadsheet_rows)
{
$this->teamId = $teamId;
$this->spreadsheet_rows = $spreadsheet_rows;
}
/**
* Execute the job.
*
* @return void
*/
public function handle(FileUploadController $uploadController)
{
$uploadController->createImportedCategories($this->teamId, $this->spreadsheet_rows);
}
}
<?php
namespace App\Http\Controllers;
use Maatwebsite\Excel\Files\ExcelFile;
use Illuminate\Support\Facades\Input;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Requests;
class SpreadsheetImportController extends ExcelFile
{
protected $delimiter = ',';
protected $enclosure = '"';
protected $lineEnding = '\r\n';
public function getFile()
{
return 'storage/tmp/tempcategories.xls';
}
public function getFilters()
{
return [
'chunk'
];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment