Софтуерно Инженерство
Loading...
ypetrov avatar ypetrov 4 Точки

Викане на променливи в един контролер от друг... Symfony

Здравейте,

Опитвам се да си изнеса метод в друг контролер, който после да достъпвам през останалите контролери за извличане на данни. Този метод ще ми носи жизнено важната информация и наистина имам крещяща нужда от адекватно решение, вместо да правя нов метод във всеки контролер и при промяна да минавам навсякъде. Прочетох, че мога да си направя метода като контролер, но цаката не сполучва, тъй като вади променливите успешно, но ги вади празни, защото метода който трябва да ги напълни още не е извикан.

Ето следните три примерни файла:

BuildingsController.php

<?php

namespace Bundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;

class BuildingsController extends Controller
{
    private $UserData;

    public function __construct()
    {
        $this->UserData = $this->get('user_controller');
    }

    /**
     * @Route ("/buildings", name="buildings")
     * @param Request $reuqest
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function buildings()
    {
        return $this->render('default/buildings.html.twig', [
            'ver'      => $this->UserData->ver,
            'resources'=> $this->UserData->getResources,
            'village'  => $this->UserData->getVillage,
        ]);
    }
}

 

Services.yml

# Learn more about services, parameters and containers at
# http://symfony.com/doc/current/service_container.html
parameters:
#    parameter_name: value

services:
    user_controller:
        class: Bundle\Controller\UserController

 

Въпросния UserController.php който ще носи информация:

<?php

namespace Bundle\Controller;

use Bundle\Entity\GameResources;
use Bundle\Entity\Villages;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class UserController extends Controller
{
    public $ver;

    public $getResources;

    public $getVillage;

    public function dataRepo(){
        $this->ver = '1';
        if(!($this->getUser()==null)) {
            $this->getResources = $this->getDoctrine()->getRepository(GameResources::class)->findOneBy(['ofPlayer' => $this->getUser()->getId()]);
            $this->getVillage = $this->getDoctrine()->getRepository(Villages::class)->findOneBy(['ownerPlayer' => $this->getUser()->getId()]);
        }
        return $this;
    }
}

Това го правя по този начин защото не намерих друг в който да си пренасям такава информация извикана един път по различните темплейт, а twig-а явно не е чак толкова гъвкав в това отношение.

Предложения? (Държа да отбележа ,че не твърдя, че това е най-добрия начин)

Ето и един dump() на извикания обект по-горе:

BuildingsController.php on line 21:
UserController {#507 ▼
  +ver: null
  +getResources: null
  +getVillage: null
  #container: null
}

 

@b.yordanov - трябва да ти кажа, че този дебъг лог който ме посъветва да гледам е сигурно един от най-безполезните на този свят :D

Тагове:
0
PHP Web Development Basics 16/12/2016 14:03:06
RoYaL avatar RoYaL SoftUni Team Trainer 6845 Точки

Това ми звучи като да може да са методи в някое Repository, а не контролерски неща? :)

Иначе нещата са NULL, защото не извикваш dataRepo() метода от контролера и те не се напълват никога.

0
16/12/2016 14:07:45
ypetrov avatar ypetrov 4 Точки

Вероятно може, но не мога да си го представя как. Така ли трябва да станат нещата? http://symfony.com/doc/current/doctrine/repository.html

Няма примери в авторските решения и нещо не се получават както се очаква нещата...

Точно така, само че като се извика dataRepo() и ми вика Call to a member function has() on null

Ето как съм опитвал да го викна:

$this->UserData = $this->get('user_controller')->dataRepo()

 

0
RoYaL avatar RoYaL SoftUni Team Trainer 6845 Точки

Като цяло, логиката да търсиш селата на играч през репото за села (Villages) ми се струва грешна.

Ако имаш Village който си има играч, то вероятно имаш и обратния mapping - играчът си има колекция от Villages.

Тогава можеш просто да кажеш $this->getUser()->getVillages() в контролера. Цялото това query-ване не е нужно :)

Но иначе линка за правене на собствени repository-та, който си дал е валиден :)

0
16/12/2016 18:51:00
ypetrov avatar ypetrov 4 Точки

Вчера почти цял ден строших и нищо не се получи с тоя мапинг с OneToOne, OneToMany и т.н., колкото и да чета документацията на Doctrine по темата, все нещо не беше наред и биеше грешка я при записване на нов потребител, я при запис на ресурсите и на края реших да го заобиколя по селския начин, но явно ще трябва пак да го мисля...

0
RoYaL avatar RoYaL SoftUni Team Trainer 6845 Точки

Е щом си тръгал по селския начин, го пиши на всякъде - то са два реда код :)

0
ypetrov avatar ypetrov 4 Точки

Два реда са само за това... като добавим и останалото и то си стана. Както и да е, ще му търся цаката манджата с грозде да стане китайско със сладко-кисел сос...

Проблема е,че като гледам цял ден грешки от типа:

Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`revo_db`.`users`, CONSTRAINT `FK_1483A5E9BF396750` FOREIGN KEY (`id`) REFERENCES `game_resources` (`ofPlayer`))
No mapping found for field 'ownerPlayer' on class 
No mapping found for field 'user' on class 
No mapping found for field 'users' on class

И как да не почна да търся друг начин след като съм опитал всички възможни варианти и комбинации и по нито един не е станало, включаеки с правене на ново на базата десетки пъти вече.. ни с копиране и преправяне на имената само става, ни с някаква си моя логика. Пълна анархия цари по тия ентитита.

0
b.yordanov avatar b.yordanov 146 Точки

На мен по-скоро ми се струва, че толкова си се объркал та чак не знаеш какво точно искаш да направиш. Погледни в профайлера на симфони (ако не си вече), там ще ти покаже кои са ти грешните ентити-та.

Иначе контролера като сървис не виждам защо да не работи, просто извикай $this->UserData = $this->get('user_controller')->dataRepo();

0