download_file invalid file 404 instead of 200 - concrete5

Is there a way to throw a 404 instead of a 200 when we try to download an invalide file "/download_file/view/myFile.test" in concrete 5. I'm using version 8.2.1
Thanks for your help

The solution was to override the DownloadFile controller and the view method:
namespace Application\Controller\SinglePage;
use PageController;
use Core;
use Page;
use Permissions;
use Concrete\Core\Entity\File\File as FileEntity;
use Concrete\Core\File\File;
use Concrete\Controller\SinglePage\DownloadFile as CoreDownloadFile;
class DownloadFile extends CoreDownloadFile
{
/**
* #param int $fID
* #param null $rcID
* #return bool
*/
public function view($fID = 0, $rcID = null)
{
//your code
//redirect to 404 whenever you want:
$this->replace('/page_not_found');
//...
}
}

Related

Symfony 5 object not found by the #ParamConverter annotation and 404 redirection

I want to redirect users to a 404 page.
My problem is that if the slug does not exist I get an error:
App\Entity\Article object not found by the #ParamConverter annotation.
Unfortunately I can't find a way to get the NULL for the condition.
/**
* #Route("/rubriques/{slugCategory}/{slug}", name="articleSingle")
*/
public function show(Article $article, String $slug): Response
{
$article = $this->repoArticle->findOneBy(['slug' => $slug]);
dd($article);
if (!$article) {
return $this->redirectToRoute('404error');
}
return $this->render("show/index.html.twig", [
'article' => $article,
]);
}
You don't need to set "Article" as your controller dependency as you don't want to use the DoctrineParamConverter to automatically find the object for you. So you should change
public function show(Article $article, String $slug): Response
{
...
}
To
public function show(string $slug): Response
{
...
}
That way, you will be able to manually find the article corresponding to the passed slug and if there is no result, you will be able to redirect the user to a 404 page.
Why dont you use this:
If the field in Article is slug you can use it directly:
/**
* #Route("/rubriques/{slugCategory}/{slug}", name="articleSingle")
*/
public function show(Article $article): Response
{
...
}
see https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/converters.html#fetch-automatically
If the field in Article is different:
/**
* #Route("/rubriques/{slugCategory}/{slug}", name="articleSingle")
* #Entity("article", expr="repository.findOneBySlug(slug)")
*/
public function show(Article $article): Response
{
...
}
where findOneBySlug has to be adepted to the correct method in the repository
see https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/converters.html#fetch-via-an-expression

How to validate data in a custom controler

I created a Entity with a custom contoller:
// api/src/Entity/UserRegistration.php
namespace App\Entity;
use ...
/**
* UserRegistraion Data
*
* #ApiResource(collectionOperations={},itemOperations={"post"={
* "method"="POST",
* "path"="/register",
* "controller"=CreateUser::class}})
*
*/
class UserRegistration
{
.....
/**
* #var string The E-mail
*
* #Assert\NotBlank
* #Assert\Email(
* message = "The email '{{ value }}' is not a valid email.",
* checkMX = true
* )
*/
public $email;
.....
And a custom Controller:
// api/src/Controller/CreateUser.php
class CreateUser
{
.....
public function __invoke(UserRegistration $data): UserRegistration
{
return $data;
}
}
When I call the controller with wrong data (e.g wrong email-address) I would expect an validation error, but it is not checked.
Is there a way to do this?
Api Platform does the validation on the result of your controller, to make sure your data persisters will receive the right information. Thus you may get invalid data when entering your controller, and need to perform the validation manually if your action needs a valid object.
The most common approaches are either using a Form, which provides among other things validation, or just the Validator as a standalone component. In your case you - since are using ApiPlatform - the latter would be the better choice as you don't need to render a form back to the user, but instead return an error response.
First you will need to inject the Validator into your Controller:
use ApiPlatform\Core\Bridge\Symfony\Validator\Exception\ValidationException;
use Symfony\Component\Validator\Validator\ValidatorInterface;
class CreateUser
{
private $validator;
public function __construct(ValidatorInterface $validator)
{
$this->validator = $validator;
}
public function __invoke(UserRegistration $data): UserRegistration
{
$errors = $this->validator->validate($data);
if (count($errors) > 0) {
throw new ValidationException($errors);
}
return $data;
}
}
You can also check how ApiPlatform does it by looking at the ValidateListener. It provides some additional features, e.g. for validation groups, which you don't seem to need at this point, but might be interesting later. ApiPlatform will then use its ValidationExceptionListener to react on the Exception you throw and render it appropriately.

Set requirements for get request parameters in symfony's controller

I have a controller which handles a GET request. I need to set requirement parameters for GET request, e.g.: 'http://localhost/site/main?id=10&sort=asc
My controller class
class IndexController extends Controller {
` /**
* #Route
* (
* "/site/main",
* name="main"
* )
*
* #Method("GET")
*/
public function mainAction(Request $request)
{
return new Response('', 200);
}
}
How could I do that?
UPD: I need to set requirement for URL parameters like
id: "\d+",
sort: "\w+"
Etc.
The same as symfony allows to do with POST request.
You can specify the requirements in the "#Route" annotation like this:
class IndexController extends Controller {
` /**
* #Route
* (
* "/site/main",
* name="main",
* requirements={
* "id": "\d+",
* "sort": "\w+"
* })
* )
*
* #Method("GET")
*/
public function mainAction(Request $request)
{
return new Response('', 200);
}
}
#Method is what you need http://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/routing.html#route-method
If you try to use this route with POST, you will have 404
I couldn't understand your question well.
However, if what you need is to set up a filter mechanism for the GET method parameters as it is already available for the URL using route requirements, I think there is no ready to use tools for this in the Route component, as commented #Yoshi.
I had to do this kind of work myself and used this. I hope it helps you too
public function indexAction(Request $request)
{
// Parameter names used in the current request
$current_request_params=array_keys($request->query->all());
// $ALLOWED_INDEX_PARAMS should be declared as Class static property array and hold names of the query parameters you want to allow for this method/action
$unallowed_request_params=array_diff($current_request_params,PersonController::$ALLOWED_INDEX_PARAMS);
if (!empty($unallowed_request_params))
{
$result=array("error"=>sprintf("Unknown parameters: %s. PLease check the API documentation for more details.",implode($unallowed_request_params,", ")));
$jsonRsp=$this->get("serializer")->serialize($result,"json");
return new Response($jsonRsp,Response::HTTP_BAD_REQUEST,array("Content-Type"=>"application/json"));
}
// We are sure all parameters are correct, process the query job ..
}

retrieve attribute from object in entity doctrine

So I have this function :
MyProject\Bundle\Entity\Audio;
/**
*
* #return string
*/
public function getStudioName()
{
return $this->getStudio()->getNom();
}
which is supposed to retrieve the attribute nom from the object Studio.
They are defined like this :
/**
* #var \MyProject\Bundle\Entity\Device
*/
private $studio;
...
/**
* Get studio
*
* #return \MyProject\Bundle\Entity\Device
*/
public function getStudio()
{
return $this->studio;
}
And the ->getNom is just also a basic return, which works fine.
So i get that following error message :
Error: Call to a member function getNom() on a non-object
I've read about lazy loading and I understand why $this->getStudio() gives me a proxy instead of an actual Device object, but I can't go further and use getNom() after that...
I've tried to add fetch : EAGER to avoid lazy loading but it still doesn't work.
Any ideas ?
It looks like property $studio can be NULL. In such a case, you need to validate if it is set. If not, return NULL.
The real code would look like this:
<?php
public function getStudioName(): ?string
{
return $this->studio ? $this->studio->getName() : null;
}

How to use object mapping with Flex, Zend, AMFPHP

File structure
customerService.PHP
include 'vo/VOCustomer.php';
include 'mydb.php';
class customerService
{
public function createCustomer(VOCustomer $cus)
{
$db = new mydb();
$db->connect();
$query = sprintf("insert into customer (CusId, CusName, CusContact,idcompany) values ('%s','%s','%s','%s')",
mysql_real_escape_string($cus->CusId),
mysql_real_escape_string($cus->CusName),
mysql_real_escape_string($cus->CusContact),
mysql_real_escape_string($cus->idcompany));
$rs = mysql_query($query) or die ("Unable to complete query.");
return 'success';
}
}
vo/VOCustomer.php
class VOCustomer {
public $CusId;
public $CusName;
public $CusContact;
public $idcompany;
}
When importing the customerService.php to a flex zend project Its possible that the data type may not return as VOCustomer sometimes it will show Object as type
How to make the passing object as VOcustomer object ?
I'm not sure the 'Connect to PHP' wizard understands type hinting.
Even if it does Zend AMF will pass an Objet not a VOCustomer to the method.
It's safer to add a PHPDoc comment:
/**
* #param VOCustomer $cus
*/
public function createCustomer($cus)
Second add dummy function to your service that returns VOCustomer. The 'Connect to PHP' wizard generates a value object only if it's returned by a service method.
/**
* #return VOCustomer
*/
public function getCustomer() {
//Do nothing
}

Resources