PHP Reddit – Telegram
PHP Reddit
33 subscribers
293 photos
37 videos
24.9K links
Channel to sync with /r/PHP /r/Laravel /r/Symfony. Powered by awesome @r_channels and @reddit2telegram
Download Telegram
Symfony 7.2 and admin react

Hi, I am trying to get admin react running. But all I get when the browser open https:localhost/admin is blank page.

This is what i hav done:

1. Create symfony project as API
2. Install platform api
3. Create some entities to try
4. Make these entities as api resource
5. Install symfony ux react along with webpack encore
6. Configure the app.js, create reactAdmin.jsx, render from twig.
6. The list of api are shown succesfully in https://localhost/api
7. The blank page shown in /admin is not pure white. It has some greyish (i think) background color and no error code from browser. It seems twig manage to render react just fine. Just nothing filling the page.

I am not what I hav done wrong. I am following symfonycast lesson. Although the lesson is based on symfony 6.2.

Best regards



https://redd.it/1it7ire
@r_php
Is it possible to use DoctrineExtension on a Many to Many relationship?

For example I would like to display the categories that have admin=true only to admins from Post collection or maybe I can decorate or overload the class that makes the join?

```
<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Entity
* @ORM\Table(name="posts")
*/
class Post
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;

/**
* @ORM\Column(type="string", length=255)
*/
private $noscript;

/**
* @ORM\Column(type="text")
*/
private $content;

/**
* @ORM\ManyToOne(targetEntity="App\Entity\Category", inversedBy="posts")
* @ORM\JoinColumn(nullable=false)
*/
private $category;
}

<?php

class Category
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;

/**
* @ORM\Column(type="string", length=255)
*/
private $name;

/**
* @ORM\Column(type="boolean")
*/
private $admin;

/**
* @ORM\OneToMany(targetEntity="App\Entity\Post", mappedBy="category")
*/
private $posts;

public function __construct()
{
$this->posts = new ArrayCollection();
}
}

https://redd.it/1itea0g
@r_php
Censor 2.0

👋 Hi community,

I'm excited to share the release 2.0 of Censor, a package designed to give your Laravel 10+ applications robust and flexible content moderation and sentiment analysis capabilities.

🚀 In this release, I just added support for:

\- Sentiment analysis
\- LLM-based checker via Prism library
\- Normalized and enriched results
\- Routes, controller, and, resources ready to use

for more detailed information, please refer to the repository README.md

GitHub repository: https://github.com/diego-ninja/laravel-censor

This is a work in progress, but it should be ready to be used in production environments.

Ideas, comments, and any kind of collaboration are always welcome. Please tell us what you think in the comments, and if you like the package, please recommend Censor or give us a star in Github.

https://redd.it/1itg255
@r_php
Php, Vscode , Php Intelephense - maybe not working correctly.

I am very new to php. I am a c# coder.

First, i am using vscode with php. If there is a better open source ide out there you can recommend that's easy to set up and use, I'll take it. I was using dream weaver, but i haven't figured out how to debug. For some reason, I couldn't cut and paste code from the code view.

While using vscode, the intelesense gives every every recommendation when I just want the recommendations from the objects class. I looked online and I saw a recommendation to install 'Php Intelephense'. I installed it and disabled the built-in intelesense, but neither become active.

Any help on getting that active would help.

https://redd.it/1itedoj
@r_php
Best practice to allow reverse-proxy caching of anonymous responses?

In my Symfony 6.4 application most paths are readable by anonymous users and responses to these anonymous requests should be cacheable by my reverse proxy server (e.g. Varnish/Fastly/Cloudflare). Cacheable responses should be identified to the proxy by having a header like `Cache-control: public, s-maxage: 604800`.

After successfully logging in, users looking at those same URIs get additional buttons and options and responses should have `Cache-control: private`. The issue is that by having a firewall configured at all, a check of the session happens internally which increments the `Session::$usageIndex` even though no data is added to the session if users aren't logged in. Because checks for session data cause the session to exist, the `AbstractSessionListener` then sets `Cache-control: private` even for anonymous requests/responses.

Based on the work of Tuğrul Topuz in [Something Wrong with AbstractSessionListener](https://github.com/symfony/symfony/issues/37113#top)\#37113 ([comment](https://github.com/symfony/symfony/issues/37113#issuecomment-643341100), [source](https://github.com/tugrul/slcc-poc/blob/17f59f4207f80d5ff5f7bcc62ca554ba7b36d909)) I added the following to my Symfony 6.4 application at `src/EventListener/EmptySessionCacheControlListener.php`:

<?php

namespace App\EventListener;

use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\EventListener\AbstractSessionListener;
use Symfony\Component\HttpKernel\KernelEvents;

/**
* Ensure that responses aren't marked private when the session is empty.
*
* AbstractSessionListener sets responses as Cache-Control: private if there is
* a firewall that *allows* authenticated users, even if there is no
* authenticated user for the current request and that request is anonymous.
*
* This listener ensures that reads to the session (such as from the standard
* firewall configuration) do not make responses to anonymous requests
* uncacheable.
*
* This class is based on the work of Tuğrul Topuz in:
* - https://github.com/symfony/symfony/issues/37113#issuecomment-643341100
* - https://github.com/tugrul/slcc-poc/blob/17f59f4207f80d5ff5f7bcc62ca554ba7b36d909/src/EventSubscriber/SessionCacheControlSubscriber.php
*/
class EmptySessionCacheControlListener
{
#[AsEventListener(event: KernelEvents::RESPONSE, priority: -999)]
public function onKernelResponse(ResponseEvent $event)
{
if (!defined(AbstractSessionListener::class.'::NO_AUTO_CACHE_CONTROL_HEADER')) {
return;
}

$request = $event->getRequest();

if (!$request->hasSession()) {
return;
}

$session = $request->getSession();

// The existence of the isEmpty() function is not guarantee because it
// isn't in the SessionInterface contract.
if (!($session instanceof Session) || !method_exists($session, 'isEmpty')) {
$fields = $session->all();

foreach ($fields as &$field) {
if (!empty($field)) {
return;
}
}
} elseif (!$session->isEmpty()) {
return;
}

$event->getResponse()->headers->set(AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER, true);
}
}

I then combine this with a listener that sets my max-age and s-maxage directives on anonymous responses:

<?php

namespace App\EventListener;

use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use
Symfony\Component\HttpKernel\KernelEvents;

/**
* Set Cache-Control headers to public for anonymous requests.
*/
final class CacheControlListener
{
public function __construct(
private int $maxAge = 300,
private int $sharedMaxAge = 604800,
) {
}

#[AsEventListener(event: KernelEvents::RESPONSE)]
public function onKernelResponse(ResponseEvent $event): void
{
if ($event->isMainRequest()) {
// Symfony firewalls seem to initialize the session even when there
// is no data in the session. Ensure that we actually have session
// data before marking the response as private.
if ($event->getRequest()->getSession()->isStarted()) {
$event->getResponse()->setPrivate();
} else {
$response = $event->getResponse();
$response->setPublic();
$response->setMaxAge($this->maxAge);
$response->setSharedMaxAge($this->sharedMaxAge);
}
}
}
}

While the addition of these two listener classes works for my purposes, I was surprised that there seems to be no documentation of what I would assume to be a commonly needed technique. The Symfony documentation on [HTTP Caching and User SessionsHTTP Caching and User Sessions](https://symfony.com/doc/current/http_cache.html#http-caching-and-user-sessions) mentions `$response->headers->set(AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER, 'true');` but not the more general case of wiring up an application to use this behavior broadly.

Am I missing something? Is there some other practice for ensuring that responses for anonymous requests are cacheable while authenticated ones are private?

https://redd.it/1ithsqf
@r_php
Help with EventListener

I want users to be redirect to 'app_test' when they try to visit an authentication page (eg. app_login and app_register) while already authenticated.
I also want the opposite. When unauthenticated users try to visit a page that requires them to be authenticated, they should be redirected to 'app_login'.

I think an EventListener would be the best choice, but the html appears a second time in the debug toolbar. (See image)

This also only happens when i do a hard refresh.

Does anyone know whats going on, and how to fix it?

If you need more info from my project, please let me know!

TIA!

My listener:

<?php

namespace App\EventListener;

use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;

#AsEventListener
class AuthRedirectListener
{
    public function construct(
        private TokenStorageInterface $tokenStorage,
        private RouterInterface $router
    ) {
    }

    public function invoke(RequestEvent $event): void
    {
        if (!$event->isMainRequest()) {
            return;
        }

        $request = $event->getRequest();
        $currentRoute = $request->attributes->get('route');
        $isLoggedIn = $this->tokenStorage->getToken()?->getUser() !== null;

        // Redirect logged-in users from auth routes to app
test
        if (inarray($currentRoute, ['applogin', 'appregister']) && $isLoggedIn) {
            $event->setResponse(new RedirectResponse($this->router->generate('app
test')));
            return;
        }

        // Redirect unauthenticated users from non-auth routes to applogin
        if (!in
array($currentRoute, 'app_login', 'app_register') && !$isLoggedIn) {
            $event->setResponse(new RedirectResponse($this->router->generate('applogin')));
            return;
        }
    }
}
<?php


namespace App\EventListener;


use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;


#[AsEventListener]
class AuthRedirectListener
{
    public function construct(
        private TokenStorageInterface $tokenStorage,
        private RouterInterface $router
    ) {
    }


    public function invoke(RequestEvent $event): void
    {
        if (!$event->isMainRequest()) {
            return;
        }


        $request = $event->getRequest();
        $currentRoute = $request->attributes->get('
route');
        $isLoggedIn = $this->tokenStorage->getToken()?->getUser() !== null;


        // Redirect logged-in users from auth routes to apptest
        if (in
array($currentRoute, 'app_login', 'app_register') && $isLoggedIn) {
            $event->setResponse(new RedirectResponse($this->router->generate('apptest')));
            return;
        }


        // Redirect unauthenticated users from non-auth routes to app
login
        if (!inarray($currentRoute, ['applogin', 'appregister']) && !$isLoggedIn) {
            $event->setResponse(new RedirectResponse($this->router->generate('app
login')));
            return;
        }
    }
}

The result:

https://preview.redd.it/2e7vujn946ke1.png?width=1912&format=png&auto=webp&s=e0ac0043e7731ca5b582682d4098f6773e9f6721

https://redd.it/1ithwmd
@r_php
Just wanted to share my new open-source Laravel app...

Hey everyone,

I've been a fan of Laravel for many years, I was the original developer of Invoice Ninja way back in 2013. I've spent the past few years working with Flutter (side note: the first thing I did after learning Flutter was build a website for it using Laravel), but I've recently started working on a new Laravel project I thought may be worth sharing here.

It's called Event Schedule, it's an all-in-one platform to create calendars, sell tickets, manage teams, and streamline event check-ins with QR codes.

\- Hosted version: https://www.eventschedule.com

\- Self-hosted version: https://github.com/eventschedule/eventschedule

It has a direct integration with Invoice Ninja which enables using the many supported payment gateways to accept online payments. It's released under the AAL license and is free to use commercially.

Cheers!



https://redd.it/1itszkd
@r_php
Symfony Security: Access Token Authentication without Users

Is it possible to use Symfony's access token authentication feature without the concept of users somehow?

My app is an API. The API should be available only for my clients. So in order to use that API you have to use a Bearer authentication token. You can get this token from my other app.
When making requests to my API, I just want to check if the token exists by making a HTTP request to my other app. I don't care about an identity of the user.

Here’s the `getUserBadgeFrom` method in my `AccessTokenExtractor` class:

public function getUserBadgeFrom(string $accessToken): UserBadge
{
try {
$response = $this->httpClient->request('GET', $this->authServerUrl . '/customer', [
'headers' => [
'Authorization' => 'Bearer ' . $accessToken,
],
]);

if ($response->getStatusCode() !== 200) {
throw new BadCredentialsException('Invalid credentials.');
}

/** @var array{id: int, email_address: string, full_name: string} $data */
$data = $response->toArray();

return new UserBadge($data['email_address']);
} catch (Throwable $e) {
throw new AuthenticationException('Authentication failed: .' . $e->getMessage(), 0, $e);
}
}


However, this approach doesn’t work because Symfony expects me to register a user provider.

Is there a way to bypass this requirement, or at least define a dummy user provider that doesn't require user entities? Any advice would be greatly appreciated!

https://redd.it/1itvsc8
@r_php
Use LiveCollectionType in existing form

I have a form for a job seeker. There's a field for job experiences(an array):
              $builder
->add('experiences', LiveCollectionType::class, [
'label' => 'job_experiences',
'entry_type' => JobExperienceType::class,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
])
->add('profile_picture', ResourceType::class, [
'label' => 'profile_picture',
])

I have no idea on how to make my form display as i want. I want something like this, but i can't make all my form live. I just want the experiences field to be live. I read the documentation but it talks about the entire form again, not just a field.

Any advices or resources please ?

https://redd.it/1itxi9n
@r_php
Symfony Twig Variables Not Available After {% include %}

Hello everyone,

I'm currently working on a Symfony project and I'm struggling to understand a behavior in Twig. I'm trying to centralize my variable definitions.

At first, I thought about defining them in twig.yaml as globals, but since some of my variables are service function calls, that's not possible. 😕

So I tried creating a separate Twig file to store my variables and including it in all the files that need them, but unfortunately, my template doesn't recognize them. 😞

Example that doesn't work (Error: "Variable name does not exist.")

{# base/base.html.twig #}

{% include "base/elements/variables.html.twig" %}

{{ name }} {# Throws an error #}

{# base/elements/variables.html.twig #}

{% set name = 'zerez' %}

Workaround that works, but I don't like it

Since it's a big project, I'd have to change a lot of variable references, which is not ideal.

{# base/base.html.twig #}

{% include "base/elements/variables.html.twig" with vars %}

{{ vars.name }} {# Works, but not convenient #}

Question:

Is there a better way to include a file in Twig and make the variables inside it globally accessible without having to use vars.something everywhere?

Thanks in advance for your help! 😊

https://redd.it/1itymik
@r_php
What s the best way to use bootstrap css and js inside twig?

I read the documentation that use webpack encore and import it inside app.js etc.

But is it for turbo use?

How do we access bootstrap css n js from twig?

https://redd.it/1iu0m0l
@r_php
Is Laravel still the best choice for development of web applications? Is there some alternative?

I am not blaming Laravel. I know everybody (from the PHP world) knows it. And they have large community, good support, etc... It is surely a good choice.

So, it looks like "why should I look over for something else"? But I've learned that long-lasting projects/frameworks/libraries (name it as you wish) will get overwhelmed at some time.

Isn't this the case of Laravel? Is it still the top choice?

https://redd.it/1itxemo
@r_php
Horrors of being a PHP dev in an old company

I just got a junior position at a small company who is in the market for over 15 years.

I had high hopes for this, the interview went great, they liked my github and my experience with other languages and data analysis. They said the system is made using a RAD software and deployed in "the cloud". I thought "ok, cool. some new things to learn at least".

That's when my dreams were crushed, the RAD system has enabled non php dev to write spaghetti code for years unchecked.

Nobody knows basic things like OOP or scalar types. Company is stuck at PHP 5.6 because of said spaghetti.

There's no svn or git to see what was modified, the only control is a database table saying "user X saved file Y" and hundreds of lines on top of each file saying what was modified.

Security is a fucking joke, not even an after thought.

They asked me to create an API to interact with the system, I was so fearful to have to build an API with php 5.6 but at least I only have to create a sdk in php, the api can be in whatever. >!but they dropped the database and nobody knows how to get up. its been 4 days and I'm still waiting!<

https://redd.it/1iu2ghz
@r_php
WIP A mini Symfony app that leverages some great features in the perspective of building APIs. Good for beginners.

Hello devs, this is a simple blogging platform https://github.com/abdellahrk/microblog that might be helpful to some beginners. Features are being added and some ideas as well.

While there are tons of resources and guides out there amongst which the Symfony Demo App, this could also complement and be of help.

https://redd.it/1iu5ydj
@r_php
Doubts about validation & doctrine collections

Hey

I am new to Symfony and recently noticed a few issues which are kind of bugging me.

While working on restful apis, I used #MapRequestPayload and #MapQueryString a lot, it seems like a nice feature, however there are unexpected behaviors. For example when you map to dto with required fields, and submit a request without body, you get HttpException from inside PayloadResolver, instead of validation related exception. Is this the most recommended way of handling data validation? I realize I can use ValidatorInterface and populate dtos manually, but this seems ugly and tedious.

Another thing, while working with lists of entities in query results, I noticed that doctrine collection offers very little functionality, and most operations end up being done on plain arrays using built in functions. Is it supposed to be like that in actual projects, or do you tend to install something to enhance collections?

https://redd.it/1iu7ezv
@r_php
I'm Joe Dixon, Engineering Team Lead of Laravel Cloud, Ask Me Anything!

Hey r/Laravel,

Next Monday, February 24, my team is launching Laravel Cloud to the world. Laravel Cloud is a fully managed infrastructure platform optimized specifically for Laravel and PHP.

I'll be hosting an AMA next Thursday, February 27 to answer your questions about Laravel Cloud. Add your questions below and I'll see you then!

https://redd.it/1iu8l8g
@r_php