Add care plugin see BT#12723

pull/2487/head
jmontoyaa 9 years ago
parent d0c1a68e27
commit a191dac57e
  1. 114
      main/cron/import_csv.php
  2. 14
      main/inc/lib/banner.lib.php
  3. 6
      main/inc/lib/database.lib.php
  4. 9
      main/inc/lib/plugin.class.php
  5. 418
      plugin/studentfollowup/Entity/CarePost.php
  6. 35
      plugin/studentfollowup/StudentFollowUpPlugin.php
  7. 2
      plugin/studentfollowup/plugin.php
  8. 106
      plugin/studentfollowup/post.php
  9. 45
      plugin/studentfollowup/view/post.html.twig
  10. 4
      src/Chamilo/CourseBundle/Entity/Repository/CNotebookRepository.php
  11. 0
      src/Chamilo/PluginBundle/Entity/.gitkeep

@ -141,8 +141,7 @@ class ImportCsv
}
if (method_exists($this, $method)) {
if (
(
if ((
$method == 'importSubscribeStatic' ||
$method == 'importSubscribeUserToCourse'
) ||
@ -184,7 +183,8 @@ class ImportCsv
'sessions',
'subscribe-static',
'courseinsert-static',
'unsubscribe-static'
'unsubscribe-static',
'care',
);
foreach ($sections as $section) {
@ -2064,6 +2064,114 @@ class ImportCsv
}
}
/**
* @param $file
* @param bool $moveFile
*/
public function importCare($file, $moveFile = false)
{
$data = Import::csv_reader($file);
$counter = 1;
$batchSize = $this->batchSize;
$em = Database::getManager();
if (!empty($data)) {
$this->logger->addInfo(count($data)." records found.");
$items = [];
foreach ($data as $list) {
$post = [];
foreach ($list as $key => $value) {
$key = (string) trim($key);
// Remove utf8 bom
$key = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $key);
$post[$key] = $value;
}
if (empty($post)) {
continue;
}
$externalId = $post['External_care_id'];
$items[$externalId] = $post;
}
ksort($items);
foreach ($items as $row) {
$insertUserInfo = api_get_user_info_from_username($row['Added_by']);
if (empty($insertUserInfo)) {
$this->logger->addInfo("User does '".$row['Added_by']."' not exists skip this entry.");
continue;
}
$insertUserInfo = api_get_user_entity($insertUserInfo['user_id']);
$userId = UserManager::get_user_id_from_original_id(
$row['External_user_id'],
$this->extraFieldIdNameList['user']
);
if (empty($userId)) {
if (empty($userInfo)) {
$this->logger->addInfo("User does '".$row['External_user_id']."' not exists skip this entry.");
continue;
}
}
$userInfo = api_get_user_entity($userId);
$createdAt = $this->createDateTime($row['Added_On']);
$updatedAt = $this->createDateTime($row['Edited_on']);
$parent = null;
if (!empty($row['Parent_id'])) {
$parentId = $items[$row['Parent_id']];
$criteria = [
'externalCareId' => $parentId
];
$parent = $em->getRepository('ChamiloPluginBundle:StudentFollowUp\CarePost')->findOneBy($criteria);
}
$tags = explode(',', $row['Tags']);
$post = new \Chamilo\PluginBundle\Entity\StudentFollowUp\CarePost();
$post
->setTitle($row['Title'])
->setContent($row['Article'])
->setExternalCareId($row['External_care_id'])
->setCreatedAt($createdAt)
->setUpdatedAt($updatedAt)
->setPrivate((int) $row['Private'])
->setInsertUser($insertUserInfo)
->setExternalSource((int) $row['Source_is_external'])
->setParent($parent)
->setTags($tags)
->setUser($userInfo)
;
$em->persist($post);
$em->flush();
if (($counter % $batchSize) === 0) {
$em->flush();
$em->clear(); // Detaches all objects from Doctrine!
}
$counter++;
}
$em->clear(); // Detaches all objects from Doctrine!
}
}
/**
* 23/4/2017 to datetime
* @param $string
* @return mixed
*/
private function createDateTime($string)
{
if (empty($string)) {
return null;
}
$date = DateTime::createFromFormat('j/m/Y', $string);
return $date;
}
/**
* @param string $file
* @param bool $moveFile

@ -339,6 +339,18 @@ function return_navigation_array()
$menu_navigation['dashboard'] = isset($possible_tabs['dashboard']) ? $possible_tabs['dashboard'] : null;
}
///if (api_is_student()) {
if (true) {
$params = array('variable = ? AND subkey = ?' => ['status', 'studentfollowup']);
$result = api_get_settings_params_simple($params);
if (!empty($result) && $result['selected_value'] === 'installed') {
$navigation['follow_up']['url'] = api_get_path(WEB_PLUGIN_PATH).'studentfollowup/post.php';
$navigation['follow_up']['title'] = get_lang('CareSystem');
$navigation['follow_up']['key'] = 'homepage';
$navigation['follow_up']['icon'] = 'homepage.png';
}
}
// Administration
if (api_is_platform_admin(true)) {
if (api_get_setting('show_tabs', 'platform_administration') == 'true') {
@ -388,7 +400,7 @@ function return_navigation_array()
if (!empty($customTabs)) {
foreach ($customTabs as $tab) {
if (api_get_setting($tab['variable'], $tab['subkey']) == 'true' &&
isset($possible_tabs[$tab['subkey']]) &&
isset($possible_tabs[$tab['subkey']]) &&
api_get_plugin_setting(strtolower(str_replace('Tabs', '', $tab['subkeytext'])), 'public_main_menu_tab') == 'true'
) {
$possible_tabs[$tab['subkey']]['url'] = api_get_path(WEB_PATH).$possible_tabs[$tab['subkey']]['url'];

@ -147,7 +147,8 @@ class Database
'ChamiloCoreBundle' => 'Chamilo\CoreBundle\Entity',
'ChamiloCourseBundle' => 'Chamilo\CourseBundle\Entity',
'ChamiloSkillBundle' => 'Chamilo\SkillBundle\Entity',
'ChamiloTicketBundle' => 'Chamilo\TicketBundle\Entity'
'ChamiloTicketBundle' => 'Chamilo\TicketBundle\Entity',
'ChamiloPluginBundle' => 'Chamilo\PluginBundle\Entity'
)
);
@ -162,7 +163,7 @@ class Database
);*/
AnnotationRegistry::registerLoader(
function($class) use ($sysPath) {
function ($class) use ($sysPath) {
$file = str_replace("\\", DIRECTORY_SEPARATOR, $class).".php";
$file = str_replace('Symfony/Component/Validator', '', $file);
$file = $sysPath.'vendor/symfony/validator'.$file;
@ -700,6 +701,7 @@ class Database
$path.'src/Chamilo/CourseBundle/Entity',
$path.'src/Chamilo/TicketBundle/Entity',
$path.'src/Chamilo/SkillBundle/Entity',
$path.'src/Chamilo/PluginBundle/Entity',
//$path.'vendor/sonata-project/user-bundle/Entity',
//$path.'vendor/sonata-project/user-bundle/Model',
//$path.'vendor/friendsofsymfony/user-bundle/FOS/UserBundle/Entity',

@ -112,6 +112,15 @@ class Plugin
return $result;
}
/**
* @return string
*/
public function getCamelCaseName()
{
$result = get_class($this);
return str_replace('Plugin', '', $result);
}
/**
* Returns the title of the plugin
* @return string

@ -0,0 +1,418 @@
<?php
/* For licensing terms, see /license.txt */
namespace Chamilo\PluginBundle\Entity\StudentFollowUp;
use Gedmo\Mapping\Annotation as Gedmo;
use Doctrine\ORM\Mapping as ORM;
/**
* CarePost
*
* @ORM\Table(name="sfu_post")
* @ORM\Entity
* @Gedmo\Tree(type="nested")
*/
class CarePost
{
/**
* @var integer
*
* @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="integer", nullable=true)
*/
protected $externalCareId;
/**
* @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\Timestampable(on="create")
* @ORM\Column(name="created_at", type="datetime")
*/
protected $createdAt;
/**
* @Gedmo\Timestampable(on="update")
* @ORM\Column(name="updated_at", type="datetime")
*/
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;
/**
* @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({"lft" = "ASC"})
*/
private $children;
/**
* @var integer
* @Gedmo\TreeLeft
* @ORM\Column(name="lft", type="integer", nullable=true, unique=false)
*/
private $lft;
/**
* @var integer
* @Gedmo\TreeRight
* @ORM\Column(name="rgt", type="integer", nullable=true, unique=false)
*/
private $rgt;
/**
* @var integer
* @Gedmo\TreeLevel
* @ORM\Column(name="lvl", type="integer", nullable=true, unique=false)
*/
private $lvl;
/**
* @var integer
* @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 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;
}
}

@ -1,11 +1,15 @@
<?php
/* For licensing terms, see /license.txt */
use Symfony\Component\Filesystem\Filesystem;
/**
* Class StudentFollowUpPlugin
*/
class StudentFollowUpPlugin extends Plugin
{
public $hasEntity = true;
/**
* @return StudentFollowUpPlugin
*/
@ -34,7 +38,23 @@ class StudentFollowUpPlugin extends Plugin
*/
public function install()
{
$pluginEntityPath = $this->getEntityPath();
if (!is_dir($pluginEntityPath)) {
mkdir($pluginEntityPath, api_get_permissions_for_new_directories());
}
$fs = new Filesystem();
$fs->mirror(__DIR__.'/Entity/', $pluginEntityPath, null, ['override']);
$table = Database::get_main_table('sfu_post');
$sql = "CREATE TABLE sfu_post (id INT AUTO_INCREMENT NOT NULL, insert_user_id INT NOT NULL, user_id INT NOT NULL, parent_id INT DEFAULT NULL, title VARCHAR(255) NOT NULL, content LONGTEXT DEFAULT NULL, external_care_id INT DEFAULT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, private TINYINT(1) NOT NULL, external_source TINYINT(1) NOT NULL, tags LONGTEXT NOT NULL COMMENT '(DC2Type:array)', attachment VARCHAR(255) NOT NULL, lft INT DEFAULT NULL, rgt INT DEFAULT NULL, lvl INT DEFAULT NULL, root INT DEFAULT NULL, INDEX IDX_35F9473C9C859CC3 (insert_user_id), INDEX IDX_35F9473CA76ED395 (user_id), INDEX IDX_35F9473C727ACA70 (parent_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;";
Database::query($sql);
$sql = "ALTER TABLE sfu_post ADD CONSTRAINT FK_35F9473C9C859CC3 FOREIGN KEY (insert_user_id) REFERENCES user (id);";
Database::query($sql);
$sql = "ALTER TABLE sfu_post ADD CONSTRAINT FK_35F9473CA76ED395 FOREIGN KEY (user_id) REFERENCES user (id);";
Database::query($sql);
$sql = "ALTER TABLE sfu_post ADD CONSTRAINT FK_35F9473C727ACA70 FOREIGN KEY (parent_id) REFERENCES sfu_post (id) ON DELETE SET NULL;";
Database::query($sql);
}
/**
@ -42,6 +62,21 @@ class StudentFollowUpPlugin extends Plugin
*/
public function uninstall()
{
$pluginEntityPath = $this->getEntityPath();
$fs = new Filesystem();
if ($fs->exists($pluginEntityPath)) {
$fs->remove($pluginEntityPath);
}
$table = Database::get_main_table('sfu_post');
$sql = "DROP TABLE $table";
Database::query($sql);
}
/**
* @return string
*/
public function getEntityPath()
{
return api_get_path(SYS_PATH).'src/Chamilo/PluginBundle/Entity/'.$this->getCamelCaseName();
}
}

@ -17,6 +17,8 @@ $form->addButtonSave(get_lang('Save'));
if ($form->validate()) {
}
$plugin_info['templates'] = array('view/post.html.twig');
$plugin_info['settings_form'] = $form;

@ -0,0 +1,106 @@
<?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;
$postId = isset($_GET['post_id']) ? (int) $_GET['post_id'] : 1;
if (empty($studentId)) {
api_not_allowed(true);
}
$isAllow = false;
$showPrivate = false;
if ($studentId === $currentUserId) {
$isAllow = true;
} else {
// Only admins and DRH that follow the user
$isAdminOrDrh = UserManager::is_user_followed_by_drh($studentId, $currentUserId) || api_is_platform_admin();
// Check if course session coach
$sessions = SessionManager::get_sessions_by_user($studentId);
$isCourseCoach = false;
if (!empty($sessions)) {
foreach ($sessions as $session) {
$sessionId = $session['session_id'];
foreach ($session['courses'] as $course) {
//$isCourseCoach = api_is_coach($sessionId, $course['real_id']);
$coachList = SessionManager::getCoachesByCourseSession($sessionId, $course['real_id']);
if (!empty($coachList) && in_array($currentUserId, $coachList)) {
$isCourseCoach = true;
break(2);
}
}
}
}
$isAllow = $isAdminOrDrh || $isCourseCoach;
$showPrivate = $isAdminOrDrh;
}
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));
}
if (!empty($postId)) {
//$criteria->andWhere(Criteria::expr()->eq('private', false));
}
$pageSize = 2;
$qb
->select('p')
->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;
$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>';
$tpl = new Template($plugin->get_lang('plugin_title'));
$tpl->assign('posts', $posts);
$tpl->assign('current_url', $url);
$tpl->assign('pagination', $pagination);
$content = $tpl->fetch('/'.$plugin->get_name().'/view/post.html.twig');
// Assign into content
$tpl->assign('content', $content);
// Display
$tpl->display_one_col_template();

@ -0,0 +1,45 @@
<h1>Care detail view</h1>
{% if posts %}
{% for post in posts %}
<h2>{{ post.title }}</h2>
<p>{{ post.content }}</p>
<p>{{ post.createdAt |date('d/m/Y') }}</p>
{% if post.private %}
<p><span class="label label-warning">Private</span></p>
{% endif %}
<p>{{ post.insertUser.completeName }}</p>
{% if post.tags %}
{% for tag in post.tags %}
{{ tag }}
{% if not loop.last %}
,
{% endif %}
{% endfor %}
{% endif %}
{% if post.parent %}
<h3>Parent</h3>
<a href="{{ current_url }}&post_id={{ post.parent.id }}">
{{ post.parent.title }}
</a>
{% endif %}
{% if post.children.count %}
<h3>Children</h3>
{% for child in post.children %}
<p>
<a href="{{ current_url }}&post_id={{ child.id }}">
{{ child.title }}
</a>
</p>
{% endfor %}
{% endif %}
{% endfor %}
<div>
{{ pagination }}
</div>
{% endif %}

@ -29,8 +29,8 @@ class CNotebookRepository extends EntityRepository
Course $course,
Session $session = null,
$orderField = 'creation_date',
$orderDirection = 'DESC')
{
$orderDirection = 'DESC'
) {
switch ($orderField) {
case 'creation_date':
$orderField = 'N.creationDate';

Loading…
Cancel
Save