Opening request value-based view without repeating code - laravel

I am trying to open different views based upon a request value. For example, if the value of $request is set to one, then view one should open. If the $request value is two, then view two should open.
My code is working fine, but right now, I will have to repeat code for each view. How can I do it without repeating the if condition?
Scenario
public function printreports(Request $request)
{
$reports = $request->get('reports');
if ($reports === 1) {
return view('teachers.report1', compact('anything'));
}
if ($reports === 2) {
return view('teachers.report2', compact('anything'));
}
}

For large amount of files with similar name pattern:
$viewName = sprintf('teachers.report%d', $request->get('reports', 1))
if (!\View::exists($viewName)) {
___ throw an error or return default view ____
}
return view($viewName, compact('anything'));

Related

Model events not fire in laravel testing

I'm writing some tests for my model when it was created/updated/deleted. When I test it manually, it worked. But when I test in test file, asserting a event dispatch always fail.
This is my test function:
public function test_booted_method_ran()
{
$model = AcCard::factory()->create();
$this->expectsEvents('eloquent.created: \App\Models\AcCard');
}
This test case always fails. I've tried to inspect expectsEvents and added dd() to check event list:
public function expectsEvents($events)
{
$events = is_array($events) ? $events : func_get_args();
$this->withoutEvents();
$this->beforeApplicationDestroyed(function () use ($events) {
$fired = $this->getFiredEvents($events);
dd($fired); // Added this code line
$this->assertEmpty(
$eventsNotFired = array_diff($events, $fired),
'These expected events were not fired: ['.implode(', ', $eventsNotFired).']'
);
});
return $this;
}
And result is an empty array.
What I tried
I tried to add this code lines above model creating
AcCard::flushEventListeners();
AcCard::boot();
AcCard::booted();
But it doesn't work.

view does not appear, only data appears

i want to passing data to view
my controller
public function create()
{
$maxcode=Product::selectRaw('MAX(RIGHT(product_code, 3)) as max')->first();
$prx='P2018-';
if($maxcode->count()>0)
{
$tmp = ((int)$maxcode->max)+1;
$newcode = $prx.sprintf("%03s", $tmp);
}
else
{
$newcode = $prx."P2018-001";
}
return $newcode;
return view('product.create', $newcode);
}
my view
...other code...
#foreach($newcode as $nc)
{{$nc->newcode}}
#endforeach
---other code...
the code works well, but the only results appear, the other code on the view does not work.
someone might be able to help me
remove return $newcode;
return view('product.create')->with('newcode',$newcode);
$newcode variable is not an array, you can not use foreach.
use {{$newcode}} in blade to display value of variable.
remove return $newcode; line and change your return function like this,
return view('product.create', compact('newcode'));

Laravel 5 - Display different views based on database query

I have the following database design
I have several different Documents I want a user to be able to create. Each document has its own view for the creation of the document, or the editing.
If the document they are trying to create has already been created, they should see the edit page for that document.
At the moment, I have the following
public function create(Project $project)
{
$documentTypesCreated =
$project->document()
->join('document_type', 'documents.id', '=', 'document_type.documentId')
->select('document_type.documentId', 'document_type.name')
->get();
$documentLink = $_GET['documentType'];
if($documentTypesCreated->isEmpty()){
return View::make($documentLink.'Doc.create', compact('project'));
} else {
foreach($documentTypesCreated as $documentName) {
if($documentName->name != $documentLink) {
return View::make($documentLink.'Doc.create', compact('project'));
} else {
$document = Document::find($documentName->documentId);
return View::make($documentLink.'Doc.edit', compact('project', 'document'));
}
}
}
}
Breaking this up, I am doing the following:
Firstly, I get all the Documents that have been created for a Project
$documentTypesCreated =
$project->document()
->join('document_type', 'documents.id', '=', 'document_type.documentId')
->select('document_type.documentId', 'document_type.name')
->get();
I then get the Document the user is trying to create from the URL
$documentLink = $_GET['documentType'];
So lets say that the query returns that this Project has
DocumentA
DocumentB
And the documentLink shows that I am trying to create DocumentB.
Because DocumentB has already been created, I need the edit page for this Document. Firstly, I check if the query returned and Documents
if($documentTypesCreated->isEmpty()){
return View::make($documentLink.'Doc.create', compact('project'));
} else {
}
If it didnt, it will show the create page for the chosen Document. If it did, the else statement will kick in.
Within the else statement, I loop through all the Documents the query returned
foreach($documentTypesCreated as $documentName) {
}
I then do the following, and this is where my logic is failing
if($documentName->name != $documentLink) {
return View::make($documentLink.'Doc.create', compact('project'));
} else {
$document = Document::find($documentName->documentId);
return View::make($documentLink.'Doc.edit', compact('project', 'document'));
}
If the document Name from the query is not equal to the document I am trying to create, then I show the create page for that Document. Otherwise, I show the edit page.
Now lets get back to where I chose DocumentB. I know that I have already created this Document, so I should see its edit page. However, because DocumentA is the first result returned in the query, the above statement looks like the following
if("DocumentA" != "DocumentB") {
return View::make($documentLink.'Doc.create', compact('project'));
} else {
$document = Document::find($documentName->documentId);
return View::make($documentLink.'Doc.edit', compact('project', 'document'));
}
So it is going to show the create page for DocumentB, not the edit page. If DocumentB was the first result returned, then the edit page would be displayed.
I Hope this makes sense. How can I get it displaying the correct view for the document?
Thanks
Controller
Base on your query - you may set these variables manually
$create = true;
$edit = false;
Logic
if ($query == 'any logic') {
$create = true;
$edit = false;
}else{
$create = false;
$edit = edit;
}
Then, send them over to your view.
View
#if($create == true)
//.. Show Create Form
#else
// .. Show Edit Form
#stop
Then, your view will render base the result of your query. I hope this help !

Magento product save, how to detect whether product data has been changed

While editting a product in the backend I need to know whether any of it's data has been changed or not?
$product->hasDataChanges() always return true even I didn't modify any fields.
Why does $product->hasDataChanges() always return true even I didn't modify any fields.?
Looking into the Varien_Object function setData function it appears that hasDataChanges is always set to true even if technically the data has not changes.
public function setData($key, $value=null)
{
$this->_hasDataChanges = true;
if(is_array($key)) {
$this->_data = $key;
$this->_addFullNames();
} else {
$this->_data[$key] = $value;
if (isset($this->_syncFieldsMap[$key])) {
$fullFieldName = $this->_syncFieldsMap[$key];
$this->_data[$fullFieldName] = $value;
}
}
return $this;
}
Solution:
When you have a model which is an type of Mage_Core_Model_Abstract, then you can easily get the previous data (original data) on save using public function getOrigData($key=null) method.
getOrigData() returns the data in the object at the time it was initialized/populated.
After the model is initialised you can update that data and getData() will return what you currently have in that object.
Have a look at Varien_Object (getOrigData,setOrigData) so you can have a look at how and why it is used.

Magento Custom Router loading controller but nothing else

I'm trying to get some custom routing going on in Magento using the following code (which I've only slightly modified from here https://stackoverflow.com/a/4158571/1069232):
class Company_Modulename_Controller_Router extends Mage_Core_Controller_Varien_Router_Standard {
public function match(Zend_Controller_Request_Http $request){
$path = explode('/', trim($request->getPathInfo(), '/'));
// If path doesn't match your module requirements
if ($path[1] == 'home.html' || (count($path) > 2 && $path[0] != 'portfolios')) {
return false;
}
// Define initial values for controller initialization
$module = $path[0];
$realModule = 'Company_Modulename';
$controller = 'index';
$action = 'index';
$controllerClassName = $this->_validateControllerClassName(
$realModule,
$controller
);
// If controller was not found
if (!$controllerClassName) {
return false;
}
// Instantiate controller class
$controllerInstance = Mage::getControllerInstance(
$controllerClassName,
$request,
$this->getFront()->getResponse()
);
// If action is not found
if (!$controllerInstance->hasAction($action)) {
return false;
}
// Set request data
$request->setModuleName($module);
$request->setControllerName($controller);
$request->setActionName($action);
$request->setControllerModule($realModule);
// Set your custom request parameter
$request->setParam('url_path', $path[1]);
// dispatch action
$request->setDispatched(true);
$controllerInstance->dispatch($action);
// Indicate that our route was dispatched
return true;
}
}
The result is a page where the template has loaded but with no content. If I comment out the $this->loadLayout() / $this->renderLayout() in my controller I can print to screen. But when I try and load a Template and/or Block it breaks somewhere.
home.html also loads fine (as the method returns false if the path is home.html).
Any assistance would be greatly appreciated.
I was implementing something similar to this and came across the same problem(That makes sense, because I copypasted your code)
before $request->setDispatched(true);
I added $request->setRouteName('brands'); (brands is the frontname of my module).
And It worked.Don't know if It'll work for you, but definetely there was something missing so that magento didn't know what layout to apply, because I could tell that teh controller was being reached.

Resources