I have laravel project with voyager admin panel. Right now I need to see statistics on my admin dashboard for products in stores but only from today. So it needs to show me all products made today, to count it and show it on my dashboard.Let me show my code:
Here is my DeltaDimmer.php:
<?php
namespace TCG\Voyager\Widgets;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;
use TCG\Voyager\Facades\Voyager;
use Carbon\Carbon;
use App\Storeone;
class DeltaDimmer extends BaseDimmer
{
/**
* The configuration array.
*
* #var array
*/
protected $config = [];
/**
* Treat this method as a controller action.
* Return view() or other content to display.
*/
public function run()
{
$count = Storeone::where('created_at', '=', Carbon::today())->count();
//$count = \App\Storeone::where('created_at', '=', Carbon::today())->count();
$string = 'Rad: ';
return view('voyager::dimmer', array_merge($this->config, [
'icon' => 'voyager-eye',
'title' => "{$string} {$count}",
'text' => 'Optika Podgorica/Delta',
'button' => [
'text' => 'Prikazi',
'link' => route('voyager.optikadelta.index'),
],
'image' => voyager_asset('images/widget-backgrounds/04.jpeg'),
]));
}
/**
* Determine if the widget should be displayed.
*
* #return bool
*/
public function shouldBeDisplayed()
{
return Auth::user()->can('browse', Voyager::model('Post'));
}
}
So this is my DeltaDimmer.php. This line $count = Storeone::where('created_at', '=', Carbon::today())->count(); should count my products in Storeone only for today but right now it is showing me 0 and I made a few a products just for test. What I'm doing wrong?
use whereDate instead of comparing with only where
$count = Storeone::whereDate('created_at', Carbon::today())->count();
Related
I have a list, in which I have a delete button for each entry, which works flawlessly, as do the create function. I'm trying to add an edit button, and can manage to create the popup that requests the new name.
When I create a new entry and try to edit it, it shows me the create form again. When I try to edit an older entry, it tells me that
Oh snap! Change a few things up and try submitting again.
The category.name field is required.
My full code is here, for completion:
namespace App\Orchid\Screens;
use Orchid\Screen\Screen;
use Orchid\Screen\Fields\Input;
use Orchid\Support\Facades\Layout;
use Orchid\Screen\TD;
use Orchid\Screen\Actions\ModalToggle;
use App\Models\Category;
use Illuminate\Http\Request;
use Orchid\Screen\Actions\Button;
class CategoryScreen extends Screen
{
/**
* Fetch data to be displayed on the screen.
*
* #return array
*/
public function query(): iterable
{
return [
'categories' => Category::latest()->get(),
];
}
/**
* The name of the screen displayed in the header.
*
* #return string|null
*/
public function name(): ?string
{
return 'Category Screen';
}
/**
* The screen's action buttons.
*
* #return \Orchid\Screen\Action[]
*/
public function commandBar(): iterable
{
return [
ModalToggle::make('category')
->icon('plus')
->method('create')
->modal('createCategory'),
];
}
/**
* The screen's layout elements.
*
* #return \Orchid\Screen\Layout[]|string[]
*/
public function layout(): iterable
{
return [
Layout::table('categories', [
TD::make('name'),
// Create a delete button
TD::make('Actions')
->alignRight()
->render(function (Category $category) {
return Button::make('')
->icon('trash')
->confirm(
'After deleting, the category will be gone forever.'
)
->method('delete', [
'category' => $category->id,
]);
}),
TD::make('Actions')
->alignRight()
->render(function (Category $category) {
return Button::make('')
->icon('pencil')
->modal('editCategoryModal', [
'category' => $category,
])
->method('edit', [
'category' => $category->id,
]);
}),
]),
Layout::modal('createCategory', [
Layout::rows([
Input::make('category.name')
->title('Name')
->placeholder('Enter category name'),
]),
])
->title('Create category')
->applyButton('Create'),
];
}
// Make a create method that validates name field
public function create(Request $request)
{
$request->validate([
'category.name' => 'required|max:255',
]);
// Create a new category
$category = new Category();
$category->organisation_id = auth()->user()->organisation_id;
$category->name = $request->category['name'];
$category->save();
}
// Make a delete method that deletes the category
public function delete(Request $request)
{
$category = Category::find($request->category);
$category->delete();
}
// Make an edit method that validates name field
public function edit(Request $request)
{
$request->validate([
'category.name' => 'required|max:255',
]);
// Update the category
$category = Category::find($request->category->id);
$category->name = $request->category['name'];
$category->save();
}
public function editCategoryModal(): iterable
{
return [
Layout::modal('editCategory', [
Layout::rows([
Input::make('category.name')
->title('Name')
->placeholder('Enter category name'),
]),
])
->title('Edit category')
->applyButton('Save')
];
}
}
And my site, as it looks:
And the form, when I press the edit button (the pencil):
I am quite new to Laravel Orchid, so I admit that I might be going about this the totally wrong way, but the documentation does not include an example on how to do this.
Thank you.
You should use async functions to edit a Model on the same page (with modal)
Link : https://orchid.software/en/docs/modals/#asynchronous-data-loading
and you should also define all modals in the layouts section, not in a separate function.
I want to alter the file_name data before returning it to the view. Currently i'm doing:
$ci = CI::where('user_id',Auth::id())->get();
return $$ci->map(function($item){
return collect([
'id' => $item->id,
'title' => $item->title,
'description' => $item->description,
'file_name' => $this->archiving->url.'/media/content/'.$item->file_name // the part i need to alter
]);
});
this works fine, but i need to put in the 'id,title,description'(basically all the other data that i'm not altering) or else the result will only give me the file_name. Is there a better way of doing this? Thanks
You can set Accessors & Mutators
class CI extends Model
{
/**
* Get the file path
*
* #param string $value
* #return string
*/
public function getFileNameAttribute($file_name)
{
return $this->archiving->url.'/media/content/'.$file_name;
}
}
Check more abount Accessors & Mutators
As the title states, I'm getting an odd error in Laravel 5. I'm new to Laravel, and this week I dived into Jobs/Queues. I've gotten an "Undefined Variable: $errors" error in the past, and that one I was able to understand and fix. But now, I can't seem to get past this one. To my knowledge, everything looks fine. The following breakdown will (hopefully) give you an idea of what I'm doing/where the error happens:
class PostFormFields extends Job implements SelfHandling
{
use InteractsWithQueue, SerializesModels;
/**
* The id (if any) of the Post row
*/
protected $id;
/**
* List of fields and default value for each field
*/
protected $fieldList = [
'title' => '',
'subtitle' => '',
'page_image' => '',
'content' => '',
'meta_description' => '',
'is_draft' => '8',
'publish_date' => '',
'publish_time' => '',
'layout' => 'blog.layouts.post',
'tags' => [],
];
/**
* Create a new job instance.
*
* #return void
*/
public function __construct($id = null)
{
$this->id = $id;
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
$fields = $this->fieldList;
if($this->id)
{
$fields = $this->fieldsFromModel($this->id, $fields);
} else {
$when = Carbon::now()->addHour();
$fields['publish_date'] = $when->format('M-j-Y');
$fields['publish_time'] = $when->format('g:i A');
}
/**
* Populate with old values, if they exist
* #var [type]
*/
foreach ($fields as $fieldName => $fieldValue)
{
$fields[$fieldName] = old($fieldName, $fieldValue);
}
$fields = array_merge($fields, ['allTags' => Tag::lists('tag')->all()]);
return $fields;
}
Above is the code inside the handler function of my Job class, the file it sits in is called PostFormFields.php. It's job, essentially, is just to return an array filled with all the values pertaining to a post, based on the Post Model and what's in the database that pertains to that specific Post ('title','content',etc) if a user's entered them in the past
public function create()
{
$data = $this->dispatch(new PostFormFields());
$data['title'] = 'testing';
var_dump($data);
return view('admin.post.create', $data);
}
Above is the code inside my PostController class, in the create() method. As you can tell, I'm using a resource controller for my Post Controller. It dispatches the PostFormFields Job and stores all the returned data in an array $data. However, since the create() method will be used to create a new post, only the keys should be returned, with values set to their default value ''.
This works. As you can see, i run a 'var_dump()' on the variable $data to see what, if anything, is returned. I then pass the $data array to the create View. This is where the error comes up.
Laravel "Undefined Varieble" Error
Above is a picture of the error I get when I try to access the /create route. It's clear that the $data does have the $title variable defined, as well as all the other keys in the array. Why am I getting an "Undefined Variable" array when I clearly have it defined by the time it's sent to the create View?
The line of code is says the error is in is the following:
<input type="text" class="radius" name="title" id="title" value="{{ $title }}">
You have to pass that array to view via compact function of laravel. So that you can use it in view as you want.
Please check about compact here - https://laracasts.com/discuss/channels/general-discussion/phps-compact-pros-and-cons?page=1
public function create()
{
$data = $this->dispatch(new PostFormFields());
$data['title'] = 'testing';
var_dump($data);
return view('admin.post.create', compact('data'));
}
I'm using league/fractal with JsonApiSerializer,
I've got users collection for json output.
Now I want to add some filters data to this json response (like users count for current filters).
I got this:
$resource = new Collection($dataProvider->getData(), new UserTransformer());
//the only way to include some not directly linked data i found is using setMeta():
$resource->setMetaValue('projects', $dataProvider->getProjects());
$resource->setMetaValue('somes', $dataProvider->getTasks());
But! 'projects' & 'somes' collections (yes, they are collection too) also included with 'data' key in it.
So, I've got this structure:
{
'data' => [
{//user1},{//user2},...
],
'meta' => {
'projects' => {
'data' => {...}
},
'somes' => {
'data' => {...}
}
}
}
but I want something like:
{
'data' => [
{//user1},{//user2},...
],
'meta' => {
'projects' => {...}, //there is no 'data' key
'somes' => {...} //there is no 'data' key
}
}
What should I do?
This is kinda hack but works fine without refactor Scope class which hardcoded in fractal's League\Fractal\Manager::createData() and is only way to use your own Scope class realization is to overload this method in Manager's extension.
<?php
use League\Fractal\Serializer\JsonApiSerializer;
/**
* Class EmbedSerializer
*/
class EmbedSerializer extends JsonApiSerializer
{
const RESOURCE_EMBEDDED_KEY = 'embedded';
/**
* Serialize a collection.
*
* #param string $resourceKey
* #param array $data
* #return array
*/
public function collection($resourceKey, array $data)
{
return $resourceKey === self::RESOURCE_EMBEDDED_KEY ? $data : [$resourceKey ?: 'data' => $data];
}
/**
* Serialize an item.
*
* #param string $resourceKey
* #param array $data
* #return array
*/
public function item($resourceKey, array $data)
{
return $resourceKey === self::RESOURCE_EMBEDDED_KEY ? $data : [$resourceKey ?: 'data' => [$data]];
}
}
So, now i could use it like:
/** #var $this->fractal League\Fractal\Manager */
$this->fractal->setSerializer(new EmbedSerializer());
$projectsCollection = $this->fractal->createData(
new Collection($projects, new UserProjectTransformer(), 'embedded')
)->toArray();
$resource = new Collection($users, new UserTransformer());
$resource->setMetaValue('projects', $projectsCollection);
That's all u need. Hope this will be helpful.
I am now using the FOSRestBundle in order to build a REST API within my Symfony application. The idea for now is to list some locations(hotels, restaurants...), I managed to configure the automatic routes with FOSRestBundle like:
/api/locations , /api/locations/{id} , /api/locations/{name}/detail
with this controller:
class LocationController extends FOSRestController implements ClassResourceInterface
{
/**
* GET /locations
*
* #return Array
*
*/
public function cgetAction()
{
$locations = $this->getDoctrine()
->getManager()
->getRepository('VisitBILocationsBundle:Location')
->findAll();
if (!$locations) {
return array(
'locations' => $locations,
'status' => 1
);
}
return array(
'locations' => $locations,
'status' => 0
);
}
/**
* GET /locations/{locationId}
*
* #return Array
*
*/
public function getAction($id)
{
$location = $this->getDoctrine()
->getManager()
->getRepository('VisitBILocationsBundle:Location')
->findBy(array('id' => $id));
if (!$location) {
return array(
'location' => $location,
'status' => 1
);
}
return array(
'location' => $location,
'status' => 0
);
}
/**
* GET /locations/{name}/detail
*
* #return Array
*/
public function getDetailAction($name)
{
$detail = $this->getDoctrine()
->getManager()
->getRepository('VisitBILocationsBundle:LocationDetail')
->findBy(array('name' => $name));
if (!$detail) {
return array(
'locationDetail' => $detail,
'status' => 1
);
}
return array(
'locationDetail' => $detail,
'status' => 0
);
}
}
I've been struggling with this, but would anyone know how should I proceed to generate one custom url like this:
/api/locations/nearby/{latitude}/{longitude}
The idea is that I would provide my own latitude and longitude, and the backend will calculate and provide the locations which are the closest to me.
Of course I've looked at the documentation of FOSRestBundle for manual route configuration, but since I spent some time trying to do it, I come here to ask for some help :)
If you want to manually define a route, it should just be as simple as adding the route to the existing routing configuration. How exactly you do it depends on how you're handling the routing configuration: annotation, yaml, or xml.
Option 1: YAML
In the routing.yml file (ex: src/Vendor/MyBundle/Resources/config/routing.yml) add something like:
location_nearby:
pattern: /api/locations/nearby/{latitude}/{longitude}
defaults: { _controller: "MyBundle:Location:nearby" }
requirements:
_method: GET
which would correspond to this method in LocationController:
public function nearbyAction($latitude, $longitude) { ... }
Option 2: Annotations
Add this use statement to the Controller file:
use FOS\RestBundle\Controller\Annotations\Get;
and then define the route above the controller method:
/**
* Return a nearby location
* #Get("/api/locations/nearby/{latitude}/{longitude}")
*/
public function nearbyAction($latitude, $longitude) { ... }
OK here is how to proceed, works fine for me:
I use the annotation system to route /locations/nearby/{latitude}/{longitude}
/**
* Return a nearby location
* #Get("/locations/nearby/{latitude}/{longitude}", requirements={"latitude" = "[-+]?(\d*[.])?\d+", "longitude" = "[-+]?(\d*[.])?\d+"})
*/
public function nearbyAction($latitude, $longitude) {...}
Then I have to specify float numbers with: requirements={"latitude" = "[-+]?(\d*[.])?\d+", "longitude" = "[-+]?(\d*[.])?\d+"}
Those will still be interpreted as string by the controller: "64.1333", I just have to use this in the controller:
floatval($latitude)
to get url parameters as float and then do my calculations!