Frage

Sorry if the title is a little confusing. Couldn't think of a good way to summarise what I am asking.

On the site I'm building, I need to allow pages to have sub-pages. I have written the route for the pages to work like this:

/category/parentName/childName (eg /business/text-elements/links)

however as both parent and child exist within the same table. I can't work out how to write the query to return the child page. Here is what I have so far:

public function findByUrlJoinedToSectorAndParent($sector, $pageParent, $pageUrl)
{
    $query = $this->getEntityManager()
        ->createQuery('
            SELECT p, s FROM acmeStyleGuideBundle:PageContent p
            JOIN p.pageSector s
            LEFT JOIN p.pageTypes t
            WHERE p.pageUrl = :url
            AND s.sectorName = :sector
            AND p.PageParent = :parent
            AND t.typeName != :type'
        )
        ->setParameter('url', $pageUrl)
        ->setParameter('sector', $sector)
        ->setParameter('parent', $pageParent)
        ->setParameter('type', 'Section Headers');

    try {
        return $query->getResult();
    } catch (\Doctrine\ORM\NoResultException $e) {
        return null;
    }
}

Now, this DOES actually work. However it doesn't match the route. At the moment the route needs to look like this in order to find the child page:

/category/parentID/childName (eg /business/2/links)

I can't work out how to write the query to accept the parent name, as you can see I've queried other tables this way using a left join but I don't think I can join a table to itself.

Here are my entities for PageContent:

namespace acme\StyleGuideBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * PageContent
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="acme\StyleGuideBundle\Entity\pageContentRepository")
 */

class PageContent
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
        private $id;

    /**
     * @var ArrayCollection $pageSector_Id;
     * @ORM\ManyToMany(targetEntity="pageSector")
     * @ORM\JoinTable(
     *      name="pageSector_PageContent",
     *      joinColumns={@ORM\JoinColumn(name="PageContent_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="pageSector_Id", referencedColumnName="id")}
     *      )
     */
        protected $pageSector;

    /**
     * @ORM\ManyToOne(targetEntity="pageTypes", inversedBy="PageContent")
     * @ORM\JoinColumn(name="pageTypesId", referencedColumnName="id")
     */
        protected $pageTypes;

    /**
     * @var integer
     *
     * @ORM\Column(name="pageTypesId", type="integer")
     */

        private $pageTypesId;

    /**
     * @ORM\OneToOne(targetEntity="PageContent")
     * @ORM\JoinColumn(name="PageParent", referencedColumnName="id")
     */
        private $PageParent;

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

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

    /**
     * @var string
     *
     * @ORM\Column(name="richText", type="text")
     */
        private $richText;

    /** Converts string into sluggable url 
    *
    *   @return $text
    */
    public function slugify($text)
    {
        // replace non letter or digits by -
        $text = preg_replace('#[^\\pL\d]+#u', '-', $text);
        $text = trim($text, '-');
        if (function_exists('iconv')) $text = iconv('utf-8', 'us-ascii//TRANSLIT', $text);
        $text = strtolower($text);
        $text = preg_replace('#[^-\w]+#', '', $text);
        if (empty($text)) return 'n-a';
        return $text;
    }

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->pageSector = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set pageTypesId
     *
     * @param integer $pageTypesId
     *
     * @return PageContent
     */
    public function setPageTypesId($pageTypesId)
    {
        $this->pageTypesId = $pageTypesId;

        return $this;
    }

    /**
     * Get pageTypesId
     *
     * @return integer 
     */
    public function getPageTypesId()
    {
        return $this->pageTypesId;
    }


    /**
     * Set pageName
     *
     * @param string $pageName
     *
     * @return PageContent
     */
    public function setPageName($pageName)
    {
        $this->pageName = $pageName;
        $this->setPageUrl($pageName);

        return $this;
    }

    /**
     * Get pageName
     *
     * @return string 
     */
    public function getPageName()
    {
        return $this->pageName;
    }

    /**
     * Set pageUrl
     *
     * @param string $pageUrl
     *
     * @return PageContent
     */
    public function setPageUrl($pageUrl)
    {
        $this->pageUrl = $this->slugify($pageUrl);

        return $this;
    }

    /**
     * Get pageUrl
     *
     * @return string 
     */
    public function getPageUrl()
    {
        return $this->pageUrl;
    }

    /**
     * Set richText
     *
     * @param string $richText
     *
     * @return PageContent
     */
    public function setRichText($richText)
    {
        $this->richText = $richText;

        return $this;
    }

    /**
     * Get richText
     *
     * @return string 
     */
    public function getRichText()
    {
        return $this->richText;
    }

    /**
     * Set pageTypes
     *
     * @param \acme\StyleGuideBundle\Entity\pageTypes $pageTypes the setter for page types
     *
     * @return PageContent
     */
    public function setPageTypes(\acme\StyleGuideBundle\Entity\pageTypes $pageTypes = null)
    {
        $this->pageTypes = $pageTypes;

        return $this;
    }

    /**
     * Get pageTypes
     *
     * @return \acme\StyleGuideBundle\Entity\pageTypes 
     */
    public function getPageTypes()
    {
        return $this->pageTypes;
    }

    /**
     * Add pageSector
     *
     * @param \acme\StyleGuideBundle\Entity\pageSector $pageSector
     *
     * @return PageContent
     */
    public function addPageSector(\acme\StyleGuideBundle\Entity\pageSector $pageSector)
    {
        $this->pageSector[] = $pageSector;

        return $this;
    }

    /**
     * Remove pageSector
     *
     * @param \acme\StyleGuideBundle\Entity\pageSector $pageSector
     *
     */
    public function removePageSector(\acme\StyleGuideBundle\Entity\pageSector $pageSector)
    {
        $this->pageSector->removeElement($pageSector);
    }

    /**
     * Get pageSector
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getPageSector()
    {
        return $this->pageSector;
    }

    /**
     * Set pageSectorId
     *
     * @param array $pageSectorId The id of the page sector
     *
     * @return PageContent
     */
    public function setPageSectorId($pageSectorId)
    {
        $this->pageSectorId = $pageSectorId;

        return $this;
    }

    /**
     * Get pageSectorId
     *
     * @return array 
     */
    public function getPageSectorId()
    {
        return $this->pageSectorId;
    }

    /**
     * Set PageParent
     *
     * @param \acme\StyleGuideBundle\Entity\PageParent $PageParent The parent page of this page
     *
     * @return PageContent
     */
    public function setPageParent(\acme\StyleGuideBundle\Entity\PageContent $PageParent = null)
    {
        $this->PageParent = $PageParent;

        return $this;
    }

    /**
     * Get PageParent
     *
     * @return \acme\StyleGuideBundle\Entity\PageParent 
     */
    public function getPageParent()
    {
        return $this->PageParent;
    }

}

Here is the query I am attempting to run:

$query = $this->getEntityManager()
            ->createQuery('
                SELECT p, s, c FROM acmeStyleGuideBundle:PageContent p
                JOIN p.pageSector s
                LEFT JOIN p.pageTypes t
                LEFT JOIN p.PageContent c
                WHERE p.pageUrl = :url
                AND s.sectorName = :sector
                AND c.PageParent = :parent
                AND t.typeName != :type'
            )
            ->setParameter('url', $pageUrl)
            ->setParameter('sector', $sector)
            ->setParameter('parent', $pageParent)
            ->setParameter('type', 'Section Headers');

And here is the error I am getting.

[Semantical Error] line 0, col 192 near 'c ': Error: Class acme\StyleGuideBundle\Entity\PageContent has no association named PageContent

War es hilfreich?

Lösung

It turned out the problem was with my DQL syntax:

 SELECT p, s, c FROM acmeStyleGuideBundle:PageContent p
                JOIN p.pageSector s
                LEFT JOIN p.pageTypes t
                LEFT JOIN p.PageContent c
                WHERE p.pageUrl = :url
                AND s.sectorName = :sector
                AND c.PageParent = :parent
                AND t.typeName != :type'

Should have been

SELECT p, s, c FROM acmeStyleGuideBundle:PageContent p
                JOIN p.pageSector s
                LEFT JOIN p.pageTypes t
                LEFT JOIN p.PageParent c
                WHERE p.pageUrl = :url
                AND s.sectorName = :sector
                AND c.pageUrl = :parent
                AND t.typeName != :type'

I thought I was joining the table to itself but in actual fact I was joining the column to the table. It works perfectly now.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top