Skip to content

c_item_property to nodes conversion

Julio Montoya edited this page Dec 27, 2019 · 12 revisions

The table c_item_property has been remove in v2, instead we will use the Resource entities:

  • AbstractResource
  • ResourceNode

For example, in the announcements tool, we have a query like this:

Source from 1.11.x:

https://github.com/chamilo/chamilo-lms/blob/1.11.x/main/inc/lib/AnnouncementManager.php#L2056-L2101

<?php

$condition_session = api_get_session_condition(
    $session_id,
    true,
    true,
    'announcement.session_id'
);


if (api_get_group_id() == 0) {
    $group_condition = '';
} else {
    $group_condition = " AND (ip.to_group_id='".api_get_group_id()."' OR ip.to_group_id = 0 OR ip.to_group_id IS NULL)";
}

$sql = "SELECT 
            announcement.*, 
            ip.visibility, 
            ip.to_group_id, 
            ip.insert_user_id
        FROM $tbl_announcement announcement 
        INNER JOIN $tbl_item_property ip
        ON (announcement.c_id = ip.c_id AND announcement.id = ip.ref)
        WHERE
            announcement.c_id = $courseId AND
            ip.c_id = $courseId AND                    
            ip.tool = 'announcement' AND
            ip.visibility <> '2'
            $group_condition
            $condition_session
        GROUP BY ip.ref
        ORDER BY display_order DESC
        LIMIT 0, $maximum";

Steps:

1. AbstractResource

Set up the class like this, implement the methods required by the interface.

<?php

namespace Chamilo\CourseBundle\Entity;

class CAnnouncement extends AbstractResource implements ResourceInterface
{
}

2. ResourceRepository

Create a repository for this entity.

<?php

namespace Chamilo\CourseBundle\Repository;

final class CAnnouncementRepository extends ResourceRepository
{
}
  1. Register the Repository as a Service:

In: src/CourseBundle/Resources/config/services.yml

    Chamilo\CourseBundle\Repository\CAnnouncementRepository:
        arguments:
            $className: 'Chamilo\CourseBundle\Entity\CAnnouncement'

Because we are dealing with legacy code, we need to register this repository in the container for easy use:

<?php

namespace Chamilo\CoreBundle\Framework;

class Container
{
    /**
     * @return CAnnouncementRepository
     */
    public static function getAnnouncementRepository()
    {
        return self::$container->get('Chamilo\CourseBundle\Repository\CAnnouncementRepository');
    }

Change legacy code

<?php
        $repo = Container::getAnnouncementRepository();
        $course = api_get_course_entity($courseId);
        $session = api_get_session_entity($session_id);
        $group = api_get_group_entity(api_get_group_id());

        $qb = $repo->getResourcesByCourse($course, $session, $group);
        $qb->select('count(resource)');
        $count = $qb->getQuery()->getSingleScalarResult();

Because, getResourcesByCourse returns a QueryBuilder we can overwrite some parameters and return the count instead of all the elements. The function "getResourcesByCourse" should handle the conditions to filter by course, session or group.

Create a new Resource.

For this example, we will use the CAnnouncement resource.

Before:

<?php
     $params = [
            'c_id' => $courseId,
            'content' => $newContent,
            'title' => $title,
            'end_date' => $end_date,
            'display_order' => $order,
            'session_id' => (int) $sessionId,
        ];

        $last_id = Database::insert($tbl_announcement, $params);

After:

<?php
        $announcement = new CAnnouncement();
        $announcement
            ->setCId($courseId)
            ->setContent($newContent)
            ->setTitle($title)
            ->setEndDate(new DateTime($end_date))
            ->setDisplayOrder($order)
            ->setSessionId($sessionId)
        ;

        $repo = Container::getAnnouncementRepository();
        $repo->addResourceToCourse(
            $announcement,
            ResourceLink::VISIBILITY_PUBLISHED,
            api_get_user_entity($authorId),
            api_get_course_entity($courseId),
            api_get_session_entity($sessionId),
            api_get_group_entity()
        );
        $repo->getEntityManager()->flush();
        $last_id = $announcement->getIid();
Clone this wiki locally