Actualización

This commit is contained in:
Xes
2025-04-10 12:36:07 +02:00
parent 1da7c3f3b9
commit 4aff98e77b
3147 changed files with 320647 additions and 0 deletions

View File

@@ -0,0 +1,435 @@
<?php
/* For licensing terms, see /license.txt */
namespace Chamilo\PluginBundle\Entity\StudentFollowUp;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* CarePost.
*
* @ORM\Table(name="sfu_post")
* @ORM\Entity
* @Gedmo\Tree(type="nested")
*/
class CarePost
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue
*/
protected $id;
/**
* @var string
*
* @ORM\Column(name="title", type="string", length=255, nullable=false)
*/
protected $title;
/**
* @var string
*
* @ORM\Column(name="content", type="text", nullable=true)
*/
protected $content;
/**
* @var string
*
* @ORM\Column(name="external_care_id", type="string", nullable=true)
*/
protected $externalCareId;
/**
* @ORM\Column(name="created_at", type="datetime", nullable=true)
*/
protected $createdAt;
/**
* @ORM\Column(name="updated_at", type="datetime", nullable=true)
*/
protected $updatedAt;
/**
* @var bool
*
* @ORM\Column(name="private", type="boolean")
*/
protected $private;
/**
* @var bool
*
* @ORM\Column(name="external_source", type="boolean")
*/
protected $externalSource;
/**
* @var array
*
* @ORM\Column(name="tags", type="array")
*/
protected $tags;
/**
* @var string
*
* @ORM\Column(name="attachment", type="string", length=255)
*/
protected $attachment;
/**
* @ORM\ManyToOne(targetEntity="Chamilo\UserBundle\Entity\User", cascade={"persist"})
* @ORM\JoinColumn(name="insert_user_id", referencedColumnName="id", nullable=false)
*/
private $insertUser;
/**
* @ORM\ManyToOne(targetEntity="Chamilo\UserBundle\Entity\User", cascade={"persist"})
* @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=false)
*/
private $user;
/**
* @Gedmo\TreeParent
* @ORM\ManyToOne(targetEntity="CarePost", inversedBy="children")
* @ORM\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="SET NULL")
*/
private $parent;
/**
* @ORM\OneToMany(targetEntity="CarePost", mappedBy="parent")
* @ORM\OrderBy({"createdAt" = "DESC"})
*/
private $children;
/**
* @var int
* @Gedmo\TreeLeft
* @ORM\Column(name="lft", type="integer", nullable=true, unique=false)
*/
private $lft;
/**
* @var int
* @Gedmo\TreeRight
* @ORM\Column(name="rgt", type="integer", nullable=true, unique=false)
*/
private $rgt;
/**
* @var int
* @Gedmo\TreeLevel
* @ORM\Column(name="lvl", type="integer", nullable=true, unique=false)
*/
private $lvl;
/**
* @var int
* @Gedmo\TreeRoot
* @ORM\Column(name="root", type="integer", nullable=true, unique=false)
*/
private $root;
/**
* Project constructor.
*/
public function __construct()
{
$this->createdAt = new \DateTime();
$this->attachment = '';
}
/**
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* @param int $id
*
* @return $this
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* @param string $title
*
* @return CarePost
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* @return string
*/
public function getContent()
{
return $this->content;
}
/**
* @param string $content
*
* @return CarePost
*/
public function setContent($content)
{
$this->content = $content;
return $this;
}
/**
* @return string
*/
public function getExternalCareId()
{
return $this->externalCareId;
}
/**
* @param string $externalCareId
*
* @return CarePost
*/
public function setExternalCareId($externalCareId)
{
$this->externalCareId = $externalCareId;
return $this;
}
/**
* @return mixed
*/
public function getUser()
{
return $this->user;
}
/**
* @param mixed $user
*
* @return CarePost
*/
public function setUser($user)
{
$this->user = $user;
return $this;
}
/**
* @return bool
*/
public function isPrivate()
{
return $this->private;
}
/**
* @param bool $private
*
* @return CarePost
*/
public function setPrivate($private)
{
$this->private = $private;
return $this;
}
/**
* @return bool
*/
public function isExternalSource()
{
return $this->externalSource;
}
/**
* @param bool $externalSource
*
* @return CarePost
*/
public function setExternalSource($externalSource)
{
$this->externalSource = $externalSource;
return $this;
}
/**
* @return string
*/
public function getAttachment()
{
return $this->attachment;
}
/**
* @param string $attachment
*
* @return CarePost
*/
public function setAttachment($attachment)
{
$this->attachment = $attachment;
return $this;
}
/**
* @return mixed
*/
public function getParent()
{
return $this->parent;
}
/**
* @param mixed $parent
*
* @return CarePost
*/
public function setParent($parent)
{
$this->parent = $parent;
return $this;
}
/**
* @return int
*/
public function hasParent()
{
return !empty($this->parent) ? 1 : 0;
}
/**
* @return mixed
*/
public function getChildren()
{
return $this->children;
}
/**
* @param mixed $children
*
* @return CarePost
*/
public function setChildren($children)
{
$this->children = $children;
return $this;
}
/**
* @return mixed
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* @param mixed $createdAt
*
* @return CarePost
*/
public function setCreatedAt($createdAt)
{
$this->createdAt = $createdAt;
return $this;
}
/**
* @return mixed
*/
public function getUpdatedAt()
{
return $this->updatedAt;
}
/**
* @param mixed $updatedAt
*
* @return CarePost
*/
public function setUpdatedAt($updatedAt)
{
$this->updatedAt = $updatedAt;
return $this;
}
/**
* @return array
*/
public function getTags()
{
return $this->tags;
}
/**
* @param array $tags
*
* @return CarePost
*/
public function setTags($tags)
{
$this->tags = $tags;
return $this;
}
/**
* @return mixed
*/
public function getInsertUser()
{
return $this->insertUser;
}
/**
* @param mixed $insertUser
*
* @return CarePost
*/
public function setInsertUser($insertUser)
{
$this->insertUser = $insertUser;
return $this;
}
}

View File

@@ -0,0 +1,15 @@
Student Follow Up plugin
===
This plugin builds the basic pieces of a Student Information System
to enable teachers to give the right user experience to long-term students (and generally
life-long learners) while studying.
This means teachers can pass along information to their pears about the difficulties a student
has in studying some topics or some challenges they face that might affect their learning.
This plugin is in an early stage of development and should later (once mainstreamed) be fully
integrated into Chamilo.
*Prior to installing/uninstalling this plugin, you will need to make sure the src/Chamilo/PluginBundle/Entity folder is
temporarily writeable by the web server.*

View File

@@ -0,0 +1,245 @@
<?php
/* For licensing terms, see /license.txt */
use Chamilo\CoreBundle\Entity\SessionRelCourseRelUser;
use Chamilo\PluginBundle\Entity\StudentFollowUp\CarePost;
use Doctrine\ORM\Tools\SchemaTool;
/**
* Class StudentFollowUpPlugin.
*/
class StudentFollowUpPlugin extends Plugin
{
public $hasEntity = true;
/**
* StudentFollowUpPlugin constructor.
*/
protected function __construct()
{
parent::__construct(
'0.1',
'Julio Montoya',
[
'tool_enable' => 'boolean',
]
);
}
/**
* @return StudentFollowUpPlugin
*/
public static function create()
{
static $result = null;
return $result ? $result : $result = new self();
}
/**
* @throws \Doctrine\ORM\Tools\ToolsException
*/
public function install()
{
$em = Database::getManager();
if ($em->getConnection()->getSchemaManager()->tablesExist(['sfu_post'])) {
return;
}
$schemaTool = new SchemaTool($em);
$schemaTool->createSchema(
[
$em->getClassMetadata(CarePost::class),
]
);
}
public function uninstall()
{
$em = Database::getManager();
if (!$em->getConnection()->getSchemaManager()->tablesExist(['sfu_post'])) {
return;
}
$schemaTool = new SchemaTool($em);
$schemaTool->dropSchema(
[
$em->getClassMetadata(CarePost::class),
]
);
}
/**
* @param int $studentId
* @param int $currentUserId
*
* @return array
*/
public static function getPermissions($studentId, $currentUserId)
{
$installed = AppPlugin::getInstance()->isInstalled('studentfollowup');
if ($installed === false) {
return [
'is_allow' => false,
'show_private' => false,
];
}
if ($studentId === $currentUserId) {
$isAllow = true;
$showPrivate = true;
} else {
$isDrh = api_is_drh();
$isDrhRelatedViaPost = false;
$isCourseCoach = false;
$isDrhRelatedToSession = false;
// Only admins and DRH that follow the user.
$isAdmin = api_is_platform_admin();
// Check if user is care taker.
if ($isDrh) {
$criteria = [
'user' => $studentId,
'insertUser' => $currentUserId,
];
$repo = Database::getManager()->getRepository('ChamiloPluginBundle:StudentFollowUp\CarePost');
$post = $repo->findOneBy($criteria);
if ($post) {
$isDrhRelatedViaPost = true;
}
}
// Student sessions.
$sessions = SessionManager::get_sessions_by_user($studentId, true, true);
if (!empty($sessions)) {
foreach ($sessions as $session) {
$sessionId = $session['session_id'];
// Check if the current user is following that session.
$sessionDrhInfo = SessionManager::getSessionFollowedByDrh(
$currentUserId,
$sessionId
);
if (!empty($sessionDrhInfo)) {
$isDrhRelatedToSession = true;
break;
}
// Check if teacher is coach between the date limits.
$visibility = api_get_session_visibility(
$sessionId,
null,
true,
$currentUserId
);
if (SESSION_AVAILABLE === $visibility && isset($session['courses']) && !empty($session['courses'])) {
foreach ($session['courses'] as $course) {
$coachList = SessionManager::getCoachesByCourseSession(
$sessionId,
$course['real_id']
);
if (!empty($coachList) && in_array($currentUserId, $coachList)) {
$isCourseCoach = true;
break 2;
}
}
}
}
}
$isCareTaker = $isDrhRelatedViaPost && $isDrhRelatedToSession;
$isAllow = $isAdmin || $isCareTaker || $isDrhRelatedToSession || $isCourseCoach;
$showPrivate = $isAdmin || $isCareTaker;
}
return [
'is_allow' => $isAllow,
'show_private' => $showPrivate,
];
}
/**
* @param string $status
* @param int $currentUserId
* @param int $sessionId
* @param int $start
* @param int $limit
*
* @return array
*/
public static function getUsers($status, $currentUserId, $sessionId, $start, $limit)
{
$sessions = [];
$courses = [];
$sessionsFull = [];
switch ($status) {
case COURSEMANAGER:
$sessionsFull = SessionManager::getSessionsCoachedByUser($currentUserId);
$sessions = array_column($sessionsFull, 'id');
if (!empty($sessionId)) {
$sessions = [$sessionId];
}
// Get session courses where I'm coach
$courseList = SessionManager::getCoursesListByCourseCoach($currentUserId);
$courses = [];
/** @var SessionRelCourseRelUser $courseItem */
foreach ($courseList as $courseItem) {
$courses[] = $courseItem->getCourse()->getId();
}
break;
case DRH:
$sessionsFull = SessionManager::get_sessions_followed_by_drh($currentUserId);
$sessions = array_column($sessionsFull, 'id');
if (!empty($sessionId)) {
$sessions = [$sessionId];
}
$courses = [];
foreach ($sessions as $sessionId) {
$sessionDrhInfo = SessionManager::getSessionFollowedByDrh(
$currentUserId,
$sessionId
);
if ($sessionDrhInfo && isset($sessionDrhInfo['course_list'])) {
$courses = array_merge($courses, array_column($sessionDrhInfo['course_list'], 'id'));
}
}
break;
}
$userList = SessionManager::getUsersByCourseAndSessionList(
$sessions,
$courses,
$start,
$limit
);
return [
'users' => $userList,
'sessions' => $sessionsFull,
];
}
/**
* @return int
*/
public static function getPageSize()
{
return 20;
}
/**
* @param int $userId
*/
public function doWhenDeletingUser($userId)
{
$userId = (int) $userId;
Database::query("DELETE FROM sfu_post WHERE user_id = $userId");
Database::query("DELETE FROM sfu_post WHERE insert_user_id = $userId");
}
}

View File

@@ -0,0 +1,28 @@
<?php
exit;
require_once __DIR__.'/../../main/inc/global.inc.php';
$em = Database::getManager();
$insertUserInfo = api_get_user_entity(api_get_user_id());
$userInfo = api_get_user_entity(16);
$title = uniqid('title', true);
$post = new \Chamilo\PluginBundle\Entity\StudentFollowUp\CarePost();
$post
->setTitle($title)
->setContent($title)
->setExternalCareId(2)
->setCreatedAt(new DateTime())
->setUpdatedAt(new DateTime())
->setPrivate(false)
->setInsertUser($insertUserInfo)
->setExternalSource(0)
//->setParent($parent)
->setTags(['php', 'react'])
->setUser($userInfo)
;
$em->persist($post);
$em->flush();

View File

@@ -0,0 +1,2 @@
<?php
/* For licensing terms, see /license.txt */

View File

@@ -0,0 +1,7 @@
<?php
/* For licensing terms, see /license.txt */
if (!api_is_platform_admin()) {
api_not_allowed(true);
}
StudentFollowUpPlugin::create()->install();

View File

@@ -0,0 +1,10 @@
<?php
$strings['plugin_title'] = "Student Follow-up System";
$strings['plugin_comment'] = "Care system (Zorgdossier) [CS]
Career follow system (Structuurschema) [CFS]
Competence based evaluation system (Competentie evaluatie systeem) [CBES]";
$strings['tool_enable'] = 'Enable plugin';
$strings['CareDetailView'] = 'Mijn begeleidingen';
$strings['Private'] = 'Niet gedeeld met lesgevers';
$strings['Public'] = 'Gedeeld met lesgevers';

View File

@@ -0,0 +1,8 @@
<?php
$strings['plugin_title'] = "Student Follow-up System";
$strings['plugin_comment'] = "Care system (Zorgdossier) [CS]
Career follow system (Structuurschema) [CFS]
Competence based evaluation system (Competentie evaluatie systeem) [CBES]";
$strings['tool_enable'] = 'Enable plugin';
$strings['CareDetailView'] = 'Care detail view';

View File

@@ -0,0 +1,203 @@
<?php
/* For licensing terms, see /license.txt */
use Doctrine\Common\Collections\Criteria;
use Doctrine\ORM\Tools\Pagination\Paginator;
require_once __DIR__.'/../../main/inc/global.inc.php';
api_block_anonymous_users();
$plugin = StudentFollowUpPlugin::create();
$currentUserId = api_get_user_id();
$currentPage = isset($_REQUEST['page']) ? (int) $_REQUEST['page'] : 1;
$keyword = isset($_REQUEST['keyword']) ? Security::remove_XSS($_REQUEST['keyword']) : '';
$sessionId = isset($_REQUEST['session_id']) ? (int) $_REQUEST['session_id'] : 0;
$selectedTag = isset($_REQUEST['tag']) ? Security::remove_XSS($_REQUEST['tag']) : '';
$totalItems = 0;
$items = [];
$tags = [];
$showPrivate = false;
$pageSize = StudentFollowUpPlugin::getPageSize();
$firstResults = $pageSize * ($currentPage - 1);
$pagesCount = 0;
$isAdmin = api_is_platform_admin();
$userList = [];
if (!$isAdmin) {
$status = COURSEMANAGER;
if (api_is_drh()) {
$status = DRH;
}
$data = StudentFollowUpPlugin::getUsers(
$status,
$currentUserId,
$sessionId,
$firstResults,
$pageSize
);
$userList = $data['users'];
$fullSessionList = $data['sessions'];
} else {
$fullSessionList = SessionManager::getSessionsCoachedByUser($currentUserId);
}
if (!empty($sessionId)) {
$userList = SessionManager::get_users_by_session($sessionId);
$userList = array_column($userList, 'user_id');
}
$tagList = [];
if (!empty($userList) || $isAdmin) {
$em = Database::getManager();
$qb = $em->createQueryBuilder();
$criteria = Criteria::create();
if (!$isAdmin) {
$criteria->where(Criteria::expr()->in('user', $userList));
}
if (!empty($sessionId)) {
$criteria->where(Criteria::expr()->in('user', $userList));
}
if ($showPrivate === false) {
$criteria->andWhere(Criteria::expr()->eq('private', false));
}
$qb
->select('p')
->distinct()
->from('ChamiloPluginBundle:StudentFollowUp\CarePost', 'p')
->join('p.user', 'u')
->addCriteria($criteria)
->setFirstResult($firstResults)
->setMaxResults($pageSize)
->groupBy('p.user')
->orderBy('p.createdAt', 'desc')
;
if (!empty($keyword)) {
$keywordToArray = explode(' ', $keyword);
if (is_array($keywordToArray)) {
foreach ($keywordToArray as $key) {
$key = trim($key);
if (empty($key)) {
continue;
}
$qb
->andWhere('u.firstname LIKE :keyword OR u.lastname LIKE :keyword OR u.username LIKE :keyword')
->setParameter('keyword', "%$key%")
;
}
} else {
$qb
->andWhere('u.firstname LIKE :keyword OR u.lastname LIKE :keyword OR u.username LIKE :keyword')
->setParameter('keyword', "%$keyword%")
;
}
}
$queryBuilderOriginal = clone $qb;
if (!empty($selectedTag)) {
$qb->andWhere('p.tags LIKE :tags ');
$qb->setParameter('tags', "%$selectedTag%");
}
$query = $qb->getQuery();
$items = new Paginator($query);
$queryBuilderOriginal->select('p.tags')
->distinct(false)
->setFirstResult(null)
->setMaxResults(null)
->groupBy('p.id')
;
$tags = $queryBuilderOriginal->getQuery()->getResult();
//var_dump($queryBuilderOriginal->getQuery()->getSQL());
$tagList = [];
foreach ($tags as $tag) {
$itemTags = $tag['tags'];
foreach ($itemTags as $itemTag) {
if (in_array($itemTag, array_keys($tagList))) {
$tagList[$itemTag]++;
} else {
$tagList[$itemTag] = 1;
}
}
}
$totalItems = $items->count();
$pagesCount = ceil($totalItems / $pageSize);
}
$pagination = '';
$url = api_get_self().'?session_id='.$sessionId.'&tag='.$selectedTag.'&keyword='.$keyword.'&';
if ($totalItems > 1 && $pagesCount > 1) {
$pagination .= '<ul class="pagination">';
for ($i = 0; $i < $pagesCount; $i++) {
$newPage = $i + 1;
if ($currentPage == $newPage) {
$pagination .= '<li class="active"><a href="'.$url.'page='.$newPage.'">'.$newPage.'</a></li>';
} else {
$pagination .= '<li><a href="'.$url.'page='.$newPage.'">'.$newPage.'</a></li>';
}
}
$pagination .= '</ul>';
}
// Create a search-box
$form = new FormValidator('search_simple', 'get', null, null, null, FormValidator::LAYOUT_HORIZONTAL);
$form->addText(
'keyword',
get_lang('Search'),
false,
[
'aria-label' => get_lang('SearchUsers'),
]
);
if (!empty($fullSessionList)) {
$options = array_column($fullSessionList, 'name', 'id');
$options[0] = get_lang('SelectAnOption');
ksort($options);
$form->addSelect('session_id', get_lang('Session'), $options);
}
if (!empty($tagList)) {
$tagOptions = [];
arsort($tagList);
foreach ($tagList as $tag => $counter) {
$tagOptions[$tag] = $tag.' ('.$counter.')';
}
$form->addSelect('tag', get_lang('Tags'), $tagOptions, ['placeholder' => get_lang('SelectAnOption')]);
}
$form->addButtonSearch(get_lang('Search'));
$defaults = [
'session_id' => $sessionId,
'keyword' => $keyword,
'tag' => $selectedTag,
];
$form->setDefaults($defaults);
$tpl = new Template($plugin->get_lang('plugin_title'));
$tpl->assign('users', $items);
$tpl->assign('form', $form->returnForm());
$url = api_get_path(WEB_PLUGIN_PATH).'studentfollowup/posts.php?';
$tpl->assign('post_url', $url);
$url = api_get_path(WEB_CODE_PATH).'mySpace/myStudents.php?';
$tpl->assign('my_students_url', $url);
$tpl->assign('pagination', $pagination);
$tpl->assign('care_title', $plugin->get_lang('CareDetailView'));
$content = $tpl->fetch('/'.$plugin->get_name().'/view/my_students.html.twig');
$tpl->assign('content', $content);
$tpl->display_one_col_template();

View File

@@ -0,0 +1,20 @@
<?php
/* For licensing terms, see /license.txt */
/**
* StudentFollowUpPlugin.
*
* @package chamilo.plugin
*/
$plugin = StudentFollowUpPlugin::create();
$plugin_info = $plugin->get_info();
$form = new FormValidator('htaccess');
//$form->addText('text', 'text', ['rows' => '15']);
$form->addButtonSave(get_lang('Save'));
if ($form->validate()) {
}
$plugin_info['templates'] = ['view/post.html.twig', 'view/posts.html.twig'];
$plugin_info['settings_form'] = $form;

View File

@@ -0,0 +1,138 @@
<?php
/* For licensing terms, see /license.txt */
use Chamilo\PluginBundle\Entity\StudentFollowUp\CarePost;
use Doctrine\Common\Collections\Criteria;
use Gaufrette\Adapter\Ftp as FtpAdapter;
use Gaufrette\Filesystem;
require_once __DIR__.'/../../main/inc/global.inc.php';
$plugin = StudentFollowUpPlugin::create();
$currentUserId = api_get_user_id();
$studentId = isset($_GET['student_id']) ? (int) $_GET['student_id'] : api_get_user_id();
$postId = isset($_GET['post_id']) ? (int) $_GET['post_id'] : 1;
$action = isset($_GET['action']) ? $_GET['action'] : '';
if (empty($studentId)) {
api_not_allowed(true);
}
$permissions = StudentFollowUpPlugin::getPermissions($studentId, $currentUserId);
$isAllow = $permissions['is_allow'];
$showPrivate = $permissions['show_private'];
if ($isAllow === false) {
api_not_allowed(true);
}
$em = Database::getManager();
$qb = $em->createQueryBuilder();
$criteria = Criteria::create();
$criteria->where(Criteria::expr()->eq('user', $studentId));
if ($showPrivate == false) {
$criteria->andWhere(Criteria::expr()->eq('private', false));
}
$criteria->andWhere(Criteria::expr()->eq('id', $postId));
$qb
->select('distinct p')
->from('ChamiloPluginBundle:StudentFollowUp\CarePost', 'p')
->addCriteria($criteria)
->setMaxResults(1)
;
$query = $qb->getQuery();
/** @var CarePost $post */
$post = $query->getOneOrNullResult();
// Get related posts (post with same parent)
$relatedPosts = [];
if ($post) {
if ($action == 'download') {
$attachment = $post->getAttachment();
$attachmentUrlData = parse_url($attachment);
if (!empty($attachment) && !empty($attachmentUrlData)) {
$adapter = new FtpAdapter(
'/',
$attachmentUrlData['host'],
[
'port' => 21,
'username' => isset($attachmentUrlData['user']) ? $attachmentUrlData['user'] : '',
'password' => isset($attachmentUrlData['pass']) ? $attachmentUrlData['pass'] : '',
'passive' => true,
'create' => false, // Whether to create the remote directory if it does not exist
'mode' => FTP_BINARY, // Or FTP_TEXT
'ssl' => false,
]
);
$filesystem = new Filesystem($adapter);
if ($filesystem->has($attachmentUrlData['path'])) {
$contentType = DocumentManager::file_get_mime_type($attachmentUrlData['path']);
$response = new \Symfony\Component\HttpFoundation\Response();
$response->headers->set('Cache-Control', 'private');
$response->headers->set('Content-type', $contentType);
$response->headers->set('Content-Disposition', 'attachment; filename="'.basename($attachmentUrlData['path']).'";');
//$response->headers->set('Content-length', filesize($filename));
// Send headers before outputting anything
$response->sendHeaders();
$response->setContent($filesystem->read($attachmentUrlData['path']));
$response->send();
exit;
} else {
api_not_allowed(true);
}
} else {
api_not_allowed(true);
}
}
$qb = $em->createQueryBuilder();
$criteria = Criteria::create();
if (!empty($post->getParent())) {
$criteria->where(Criteria::expr()->in('parent', [$post->getParent()->getId(), $post->getId()]));
} else {
$criteria->where(Criteria::expr()->eq('parent', $post->getId()));
}
if ($showPrivate == false) {
$criteria->andWhere(Criteria::expr()->eq('private', false));
}
$criteria->orWhere(Criteria::expr()->eq('id', $post->getId()));
$qb
->select('p')
->distinct()
->from('ChamiloPluginBundle:StudentFollowUp\CarePost', 'p')
->addCriteria($criteria)
->orderBy('p.createdAt', 'desc')
;
$query = $qb->getQuery();
$relatedPosts = $query->getResult();
}
$tpl = new Template($plugin->get_lang('plugin_title'));
$tpl->assign('post', $post);
$tpl->assign('related_posts', $relatedPosts);
$url = api_get_path(WEB_PLUGIN_PATH).'/studentfollowup/post.php?student_id='.$studentId;
$tpl->assign('post_url', $url);
$tpl->assign(
'back_link',
Display::url(
Display::return_icon('back.png'),
api_get_path(WEB_PLUGIN_PATH).'studentfollowup/posts.php?student_id='.$studentId
)
);
$tpl->assign('information_icon', Display::return_icon('info.png'));
$tpl->assign('student_info', api_get_user_info($studentId));
$tpl->assign('care_title', $plugin->get_lang('CareDetailView'));
$content = $tpl->fetch('/'.$plugin->get_name().'/view/post.html.twig');
// Assign into content
$tpl->assign('content', $content);
// Display
$tpl->display_one_col_template();

View File

@@ -0,0 +1,84 @@
<?php
/* For licensing terms, see /license.txt */
use Doctrine\Common\Collections\Criteria;
use Doctrine\ORM\Tools\Pagination\Paginator;
require_once __DIR__.'/../../main/inc/global.inc.php';
$plugin = StudentFollowUpPlugin::create();
$currentUserId = api_get_user_id();
$studentId = isset($_GET['student_id']) ? (int) $_GET['student_id'] : api_get_user_id();
$currentPage = isset($_GET['page']) ? (int) $_GET['page'] : 1;
if (empty($studentId)) {
api_not_allowed(true);
}
$permissions = StudentFollowUpPlugin::getPermissions($studentId, $currentUserId);
$isAllow = $permissions['is_allow'];
$showPrivate = $permissions['show_private'];
if ($isAllow === false) {
api_not_allowed(true);
}
$em = Database::getManager();
$qb = $em->createQueryBuilder();
$criteria = Criteria::create();
$criteria->where(Criteria::expr()->eq('user', $studentId));
if ($showPrivate == false) {
$criteria->andWhere(Criteria::expr()->eq('private', false));
}
$pageSize = StudentFollowUpPlugin::getPageSize();
$qb
->select('p')
->distinct()
->from('ChamiloPluginBundle:StudentFollowUp\CarePost', 'p')
->addCriteria($criteria)
->setFirstResult($pageSize * ($currentPage - 1))
->setMaxResults($pageSize)
->orderBy('p.createdAt', 'desc')
;
$query = $qb->getQuery();
$posts = new Paginator($query, $fetchJoinCollection = true);
$totalItems = count($posts);
$pagesCount = ceil($totalItems / $pageSize);
$pagination = '';
$url = api_get_self().'?student_id='.$studentId;
if ($totalItems > 1) {
$pagination .= '<ul class="pagination">';
for ($i = 0; $i < $pagesCount; $i++) {
$newPage = $i + 1;
if ($currentPage == $newPage) {
$pagination .= '<li class="active"><a href="'.$url.'&page='.$newPage.'">'.$newPage.'</a></li>';
} else {
$pagination .= '<li><a href="'.$url.'&page='.$newPage.'">'.$newPage.'</a></li>';
}
}
$pagination .= '</ul>';
}
$showFullPage = isset($_REQUEST['iframe']) && 1 === (int) $_REQUEST['iframe'] ? false : true;
$tpl = new Template($plugin->get_lang('plugin_title'), $showFullPage, $showFullPage, !$showFullPage);
$tpl->assign('posts', $posts);
$tpl->assign('current_url', $url);
$url = api_get_path(WEB_PLUGIN_PATH).'studentfollowup/post.php?student_id='.$studentId;
$tpl->assign('post_url', $url);
$tpl->assign('information_icon', Display::return_icon('info.png'));
$tpl->assign('student_info', api_get_user_info($studentId));
$tpl->assign('pagination', $pagination);
$tpl->assign('care_title', $plugin->get_lang('CareDetailView'));
$content = $tpl->fetch('/'.$plugin->get_name().'/view/posts.html.twig');
// Assign into content
$tpl->assign('content', $content);
// Display
$tpl->display_one_col_template();

View File

@@ -0,0 +1,8 @@
<?php
/* For licensing terms, see /license.txt */
if (!api_is_platform_admin()) {
api_not_allowed(true);
}
StudentFollowUpPlugin::create()->uninstall();

View File

@@ -0,0 +1,26 @@
<h2>{{ 'Students' | get_lang}}</h2>
{{ form }}
{% if users %}
<table class="table table-hover table-striped data_table">
<tr>
<th>{{'Student' | get_lang }}</th>
<th>{{'Action' | get_lang }}</th>
</tr>
{% for user in users %}
<tr>
<td>{{ user.user.completeNameWithUsername }}</td>
<td>
<a href="{{ my_students_url }}student={{ user.user.id }}">
<img src="{{ '2rightarrow.png'|icon() }}">
</a>
<a href="{{ post_url }}student_id={{ user.user.id }}">
<img src="{{ 'blog.png'|icon() }}">
</a>
</td>
</tr>
{% endfor %}
</table>
<div>
{{ pagination }}
</div>
{% endif %}

View File

@@ -0,0 +1,99 @@
{% macro post_template(type, post, information_icon, post_url, current_url, related_posts) %}
{% if post %}
<div class="panel panel-default">
<div class="panel-body">
<div class="row">
<div class="col-md-8">
<h2>{{ post.title }}</h2>
<p>{{ post.content }}</p>
{% if type == 'simple' %}
{% set countElements = post.hasParent + post.children.count %}
{% if countElements %}
<a href="{{ post_url }}&post_id={{ post.id }}">
{% if countElements > 1 %}
{{ information_icon }} + {{ countElements }}
{% else %}
{{ information_icon }} + 1
{% endif %}
</a>
{% endif %}
{% endif %}
{% if post.attachment %}
<a href="{{ post_url }}&action=download&post_id={{ post.id }}" class="btn btn-default">
{{ 'Download' | get_lang }}
</a>
{% endif %}
{#{% if type == 'all' %}#}
{#{% if related_posts %}#}
{#<h3>Related</h3>#}
{#{% for post in related_posts %}#}
{#<p>#}
{#<a href="{{ post_url }}&post_id={{ post.id }}">#}
{#{{ post.title }}#}
{#</a>#}
{#</p>#}
{#{% endfor %}#}
{#{% endif %}#}
{#{% endif %}#}
</div>
<div class="col-md-4">
<p>{{ post.createdAt |date('d/m/Y') }}</p>
<p>{{ post.insertUser.completeName }}</p>
{% if post.tags %}
{% for tag in post.tags %}
{{ tag }}
{% if not loop.last %}
,
{% endif %}
{% endfor %}
{% endif %}
{% if post.private %}
<p>
<span class="label label-warning">
{{ 'Private'|get_plugin_lang('StudentFollowUpPlugin') }}
</span>
</p>
{% else %}
<p>
<span class="label label-info">
{{ 'Public'|get_plugin_lang('StudentFollowUpPlugin') }}
</span>
</p>
{% endif %}
</div>
</div>
</div>
</div>
{#{% if type == 'all' %}#}
{#{% if post.children.count %}#}
{#{% for child in post.children %}#}
{#{% if child.id != post.id %}#}
{#{{ _self.post_template('all', child) }}#}
{#{% endif %}#}
{#{% endfor %}#}
{#{% endif %}#}
{#{% endif %}#}
{% endif %}
{% endmacro %}
{% import _self as template %}
<div class="actions">
{{ back_link }}
</div>
<h2 class="text-center">
{{ care_title }} - {{ student_info.complete_name }} - {{ post.title }}
{% if post.parent %}
{{ post.parent.title }}
{% endif %}
</h2>
{% for post in related_posts %}
{{ template.post_template('all', post, information_icon, post_url, current_url) }}
{% endfor %}
{#{{ template.post_template('all', post, information_icon, post_url, current_url, related_posts) }}#}

View File

@@ -0,0 +1,11 @@
{% import 'studentfollowup/view/post.html.twig' as template %}
<h2 class="text-center">{{ care_title }} - {{ student_info.complete_name }}</h2>
{% if posts %}
{% for post in posts %}
{{ template.post_template('simple', post, information_icon, post_url, current_url) }}
{% endfor %}
<div>
{{ pagination }}
</div>
{% endif %}