From 1c1f7e76bcd29515d33fbd4acc3c1e99e4cc015d Mon Sep 17 00:00:00 2001
From: Moritz Strohm <strohm@data-quest.de>
Date: Wed, 6 Dec 2017 13:46:18 +0100
Subject: [PATCH] added tandem search function for admin users

---
 TandemPlugin.class.php          |   6 ++
 controllers/admin.php           | 166 +++++++++++++++++++++++++++++++-
 models/TandemLanguage.class.php |   5 +
 models/TandemProfile.class.php  |   7 +-
 plugin.manifest                 |   2 +-
 views/admin/search.php          |  99 +++++++++++++++++++
 6 files changed, 277 insertions(+), 8 deletions(-)
 create mode 100644 views/admin/search.php

diff --git a/TandemPlugin.class.php b/TandemPlugin.class.php
index 1e0b97c..0b13c7e 100644
--- a/TandemPlugin.class.php
+++ b/TandemPlugin.class.php
@@ -130,6 +130,12 @@ class TandemPlugin extends StudIPPlugin implements SystemPlugin, PortalPlugin
             );
             $navigation->addSubNavigation('terminated', $sub_navigation);
 
+            $sub_navigation = new Navigation(
+                dgettext('TandemPlugin', 'Tandemsuche'),
+                PluginEngine::getURL('tandemplugin/admin/search')
+            );
+            $navigation->addSubNavigation('search', $sub_navigation);
+
             $sub_navigation = new Navigation(
                 dgettext('TandemPlugin', 'Konfiguration'),
                 PluginEngine::getURL('tandemplugin/admin/config')
diff --git a/controllers/admin.php b/controllers/admin.php
index 03cde51..22b401e 100644
--- a/controllers/admin.php
+++ b/controllers/admin.php
@@ -49,7 +49,8 @@ class AdminController extends PluginController
                 $this->plugin,
                 ['status' => $this->status, 'csv_export' => '1'],
                 'admin/pairs'
-            )
+            ),
+            Icon::create('file-excel', 'clickable')
         );
         
         $sidebar->addWidget($actions);
@@ -277,6 +278,169 @@ class AdminController extends PluginController
     }
 
 
+    public function search_action()
+    {
+        if(Navigation::hasItem('/tandemplugin/admin/search')) {
+            Navigation::activateItem('/tandemplugin/admin/search');
+        }
+
+        $this->age_of_request = 0;
+
+        $this->all_languages = TandemLanguage::findAll();
+
+        if (Request::submitted('search') or Request::submitted('export')) {
+
+            if (Request::submitted('search')) {
+                $this->search_requested = true;
+                CSRFProtection::verifyUnsafeRequest();
+            }
+
+            $this->mother_language_id = trim(Request::get('mother_language_id'));
+            $this->target_language_id = trim(Request::get('target_language_id'));
+            $this->age_of_request = intval(Request::get('age_of_request'));
+
+            if (!$this->mother_language_id) {
+                PageLayout::postError(
+                    dgettext(
+                        'TandemPlugin',
+                        'Zur Suche muss eine Muttersprache ausgew�hlt werden!'
+                    )
+                );
+                return;
+            }
+
+            $this->mother_language = TandemLanguage::find(
+                $this->mother_language_id
+            );
+            $this->target_language = TandemLanguage::find(
+                $this->target_language_id
+            );
+
+            if (!$this->mother_language) {
+                PageLayout::postError(
+                    dgettext(
+                        'TandemPlugin',
+                        'Die gew�hlte Muttersprache wurde nicht in der Datenbank gefunden!'
+                    )
+                );
+                return;
+            }
+
+            $sql = "INNER JOIN tandem_user_mother_languages
+                USING (user_id)
+                WHERE
+                tandem_user_mother_languages.language_id = :mother_language_id ";
+            $sql_array = [
+                'mother_language_id' => $this->mother_language_id
+            ];
+
+            if ($this->target_language_id) {
+                if (!$this->target_language) {
+                    PageLayout::postError(
+                        dgettext(
+                            'TandemPlugin',
+                            'Die gew�hlte Zielsprache wurde nicht in der Datenbank gefunden!'
+                        )
+                    );
+                    return;
+                }
+                $sql .= "AND
+                    tandem_profiles.target_language_id = :target_language_id ";
+                $sql_array['target_language_id'] = $this->target_language_id;
+            }
+
+            if ($this->age_of_request > 0) {
+                $minimum_mkdate = new DateTime();
+                $minimum_mkdate = $minimum_mkdate->sub(
+                    new DateInterval('P' . $this->age_of_request . 'D')
+                );
+                $minimum_mkdate->setTime(0,0,0);
+
+                $sql .= "AND tandem_profiles.mkdate <= :minimum_mkdate ";
+                $sql_array['minimum_mkdate'] = $minimum_mkdate->getTimestamp();
+            }
+
+            $sidebar = Sidebar::get();
+
+            $actions = new ActionsWidget();
+            $actions->addLink(
+                dgettext('TandemPlugin', 'CSV-Export'),
+                PluginEngine::getURL(
+                    $this->plugin,
+                    [
+                        'mother_language_id' => $this->mother_language_id,
+                        'target_language_id' => $this->target_language_id,
+                        'age_of_request' => $this->age_of_request,
+                        'export' => '1'
+                    ],
+                    'admin/search'
+                ),
+                Icon::create('file-excel', 'clickable')
+            );
+            $sidebar->addWidget($actions);
+
+            $minimum_mkdate = new DateTime();
+            $minimum_mkdate = $minimum_mkdate->sub(
+                new DateInterval('P' . $this->age_of_request . 'D')
+            );
+            $minimum_mkdate->setTime(0,0,0);
+
+            $this->search_results = TandemProfile::findBySql($sql, $sql_array);
+
+            if (Request::submitted('export')) {
+                //Instead of displaying the search results we shall export them:
+                $csv_array = [
+                    [
+                        dgettext('TandemPlugin', 'Name'),
+                        dgettext('TandemPlugin', 'E-Mail Adresse'),
+                        dgettext('TandemPlugin', 'Muttersprache - Zielsprache'),
+                        dgettext('TandemPlugin', 'Gesuch eingestellt am')
+                    ]
+                ];
+
+                foreach ($this->search_results as $search_result) {
+                    $csv_array[] = [
+                        ($search_result->user
+                            ? $search_result->user->getFullName()
+                            : dgettext('TandemPlugin', 'Unbekannter Nutzer')
+                        ),
+                        $search_result->user->email,
+                        $this->mother_language->getLocalName() .
+                        ' - ' .
+                        ($search_result->target_language
+                            ? $search_result->target_language->getLocalName()
+                            : dgettext('TandemPlugin', 'Unbekannte Sprache')
+                        ),
+                        date('d.m.Y H:i', $search_result->mkdate)
+                    ];
+                }
+
+                $csv_text = array_to_csv($csv_array);
+
+                header('Content-Type: text/csv');
+                header('Content-Disposition: attachment; filename=' .
+                    dgettext('TandemPlugin', 'Tandem-Gesuche') .
+                    '-' .
+                    $this->mother_language_id .
+                    '-' .
+                    $this->target_language_id .
+                    '-' .
+                    $this->age_of_request .
+                    '_' .
+                    date('Y-m-d') .
+                    '.csv'
+                );
+
+                //For Content-Length we must use strlen instead of mb_strlen
+                //to get the number of bytes rather than the number of characters:
+                header('Content-Length: ' . strlen($csv_text));
+
+                $this->render_text($csv_text);
+            }
+        }
+    }
+
+
     public function config_action()
     {
         if(Navigation::hasItem('/tandemplugin/admin/config')) {
diff --git a/models/TandemLanguage.class.php b/models/TandemLanguage.class.php
index 6b84472..45a12ba 100644
--- a/models/TandemLanguage.class.php
+++ b/models/TandemLanguage.class.php
@@ -44,4 +44,9 @@
             return $this->name;
         }
     }
+
+    static public function findAll()
+    {
+        return self::findBySql('TRUE ORDER BY id ASC, name ASC');
+    }
 }
diff --git a/models/TandemProfile.class.php b/models/TandemProfile.class.php
index 055c714..d83c90f 100644
--- a/models/TandemProfile.class.php
+++ b/models/TandemProfile.class.php
@@ -36,7 +36,6 @@ require_once(__DIR__ . '/TandemUserMotherLanguage.class.php');
  */
  class TandemProfile extends SimpleORMap
 {
-    
     static protected function configure($config = [])
     {
         $config['db_table'] = 'tandem_profiles';
@@ -55,8 +54,7 @@ require_once(__DIR__ . '/TandemUserMotherLanguage.class.php');
         
         parent::configure($config);
     }
-    
-    
+
     public function getTargetName()
     {
         return $this->target_language->getLocalName() 
@@ -64,7 +62,4 @@ require_once(__DIR__ . '/TandemUserMotherLanguage.class.php');
             . $this->level
             . ')';
     }
-    
-    
 }
-
diff --git a/plugin.manifest b/plugin.manifest
index bcbfaab..d4c404c 100644
--- a/plugin.manifest
+++ b/plugin.manifest
@@ -1,7 +1,7 @@
 pluginname=TandemPlugin
 pluginclassname=TandemPlugin
 origin=data-quest
-version=0.6.2
+version=0.6.3
 description=Dieses Plugin erm�glicht es, Sprachtandems innerhalb der Stud.IP Platform zu bilden.
 studipMinVersion=3.5
 studipMaxVersion=3.9.99
diff --git a/views/admin/search.php b/views/admin/search.php
new file mode 100644
index 0000000..29a2441
--- /dev/null
+++ b/views/admin/search.php
@@ -0,0 +1,99 @@
+<form class="default" action="<?= PluginEngine::getLink(
+    $plugin,
+    [],
+    'admin/search'
+    ) ?>" method="post">
+    <?= CSRFProtection::tokenTag() ?>
+    <fieldset>
+        <legend>
+            <?= dgettext('TandemPlugin', 'Suche nach Tandem-Gesuchen') ?>
+        </legend>
+        <label>
+            <?= dgettext('TandemPlugin', 'Muttersprache') ?>
+            <select name="mother_language_id">
+                <option value="" selected="selected">
+                    <?= dgettext('TandemPlugin', '(bitte w�hlen)') ?>
+                </option>
+                <? foreach($all_languages as $al): ?>
+                    <option value="<?= htmlReady($al->id) ?>"
+                        <?= ($mother_language_id == $al->id
+                            ? 'selected="selected"'
+                            : ''
+                        ) ?>>
+                        <?= htmlReady($al->getLocalName()) ?>
+                    </option>
+                <? endforeach ?>
+            </select>
+        </label>
+        <label>
+            <?= dgettext('TandemPlugin', 'Gesuchte Sprache') ?>
+            <select name="target_language_id">
+                <option value="" selected="selected">
+                    <?= dgettext('TandemPlugin', '(bitte w�hlen)') ?>
+                </option>
+                <? foreach($all_languages as $al): ?>
+                    <option value="<?= htmlReady($al->id) ?>"
+                        <?= ($target_language_id == $al->id
+                            ? 'selected="selected"'
+                            : ''
+                        ) ?>>
+                        <?= htmlReady($al->getLocalName()) ?>
+                    </option>
+                <? endforeach ?>
+            </select>
+        </label>
+        <label>
+            <?= dgettext('TandemPlugin', 'Mindestalter des Gesuchs in Tagen') ?>
+            <input type="number" min="0" step="1" name="age_of_request"
+                   value="<?= (string)$age_of_request ?>">
+        </label>
+        <?= \Studip\Button::create(
+                dgettext('TandemPlugin', 'Suchen'),
+                'search'
+        ) ?>
+    </fieldset>
+    <? if ($search_results): ?>
+        <table class="default">
+            <thead>
+                <tr>
+                    <th><?= dgettext('TandemPlugin', 'Name') ?></th>
+                    <th><?= dgettext('TandemPlugin', 'E-Mail Adresse') ?></th>
+                    <th><?= dgettext('TandemPlugin', 'Muttersprache - Zielsprache') ?></th>
+                    <th><?= dgettext('TandemPlugin', 'Gesuch eingestellt am') ?></th>
+                </tr>
+            </thead>
+            <tbody>
+                <? foreach ($search_results as $result): ?>
+                    <tr>
+                        <td>
+                            <?= $result->user
+                                ? htmlReady($result->user->getFullName())
+                                : dgettext('TandemPlugin', 'Unbekannter Nutzer') ?>
+                        </td>
+                        <td>
+                            <a href="mailto:<?= htmlReady($result->user->email) ?>">
+                                <?= htmlReady($result->user->email) ?>
+                            </a>
+                        </td>
+                        <td>
+                            <?= htmlReady($mother_language->getLocalName()) ?>
+                            -
+                            <?= $result->target_language
+                                ? htmlReady($result->target_language->getLocalName())
+                                : dgettext('TandemPlugin', 'Unbekannte Sprache') ?>
+                        </td>
+                        <td><?= htmlReady(date('d.m.Y H:i', $result->mkdate)) ?></td>
+                    </tr>
+                <? endforeach ?>
+            </tbody>
+        </table>
+    <? endif ?>
+    <? if ($search_requested and !$search_results): ?>
+        <?= MessageBox::info(
+            dgettext(
+                'TandemPlugin',
+                'Es wurden keine passenden Suchergebnisse gefunden!'
+            )
+        ) ?>
+    <? endif ?>
+</form>
-- 
GitLab