Ejemplo n.º 1
0
 /**
  * @inheritDoc
  *
  * @param string $template
  * @param string $cache_id
  * @param string $compile_id
  * @param string $parent
  * @return void
  */
 public function display($template = 'page.tpl', $cache_id = null, $compile_id = null, $parent = null)
 {
     if ($this->isFramed()) {
         $this->addStylesheet(DataUtilities::URLfromPath(__DIR__ . '/../css/StMarksSmarty.css') . '?isFramed=true', self::KEY);
     }
     $this->assign('isFramed', $this->isFramed());
     parent::display($template, $cache_id, $compile_id, $parent);
 }
Ejemplo n.º 2
0
             $sections[$section['metadata']['id']] = $section;
         }
         $section = array();
         $section['metadata']['id'] = $d['CourseID'];
         foreach ($d as $column => $value) {
             switch ($column) {
                 case 'ClassName':
                     $section['metadata']['name'] = DataUtilities::titleCase($value);
                     break;
                 case 'TeacherName':
                     $section['metadata']['teacher'] = $value;
                     break;
                 default:
                     if (preg_match('/Book\\d+/', $column)) {
                         if (!empty($value)) {
                             $section['books'][] = DataUtilities::titleCase($value);
                         }
                     }
             }
         }
     }
     $section['students'][] = $d['StudentName'];
 }
 if (!empty($section['metadata']['id'])) {
     $sections[$section['metadata']['id']] = $section;
 }
 $smarty->assign('teacherDeadline', date('l, F j', strtotime($_REQUEST['teacher-deadline'])));
 $smarty->assign('deptDeadline', date('l, F j', strtotime($_REQUEST['dept-deadline'])));
 $smarty->assign('blanks', isset($_REQUEST['blanks']) ? $_REQUEST['blanks'] : 0);
 $smarty->assign('sections', $sections);
 $smarty->display('book-list/sheet.tpl');
Ejemplo n.º 3
0
<?php

require_once __DIR__ . '/vendor/autoload.php';
require_once __DIR__ . '/constants.inc.php';
use smtech\CanvasManagement\Toolbox;
use smtech\ReflexiveCanvasLTI\LTI\ToolProvider;
use Battis\DataUtilities;
@session_start();
// TODO suppressing warnings is wrong
/* prepare the toolbox */
if (empty($_SESSION[Toolbox::class])) {
    $_SESSION[Toolbox::class] = Toolbox::fromConfiguration(CONFIG_FILE);
}
$toolbox =& $_SESSION[Toolbox::class];
/* set the Tool Consumer's instance URL, if present */
if (empty($_SESSION[CANVAS_INSTANCE_URL])) {
    if (!empty($_SESSION[ToolProvider::class]['canvas']['api_domain'])) {
        $_SESSION[CANVAS_INSTANCE_URL] = 'https://' . $_SESSION[ToolProvider::class]['canvas']['api_domain'];
    } else {
        $_SESSION[CANVAS_INSTANCE_URL] = $toolbox->config('TOOL_CANVAS_API')['url'];
    }
}
/* cache per-instance */
$toolbox->cache_pushKey(parse_url($_SESSION[CANVAS_INSTANCE_URL], PHP_URL_HOST));
/* Configure smarty templating */
/* FIXME this is sometimes superfluous overhead (e.g. action=config) */
$toolbox->smarty_prependTemplateDir(__DIR__ . '/templates', basename(__DIR__));
$toolbox->getSmarty()->addStylesheet(DataUtilities::URLfromPath(__DIR__ . '/css/canvas-management.css'), basename(__DIR__));
$toolbox->smarty_assign(['title' => $toolbox->config('TOOL_NAME'), 'category' => DataUtilities::titleCase(preg_replace('/[\\-_]+/', ' ', basename(__DIR__))), 'APP_URL' => $toolbox->config('APP_URL'), 'CANVAS_INSTANCE_URL' => $_SESSION[CANVAS_INSTANCE_URL], 'navbarActive' => basename(dirname($_SERVER['REQUEST_URI']))]);
Ejemplo n.º 4
0
require_once __DIR__ . '/vendor/autoload.php';
use smtech\CanvasHack\Toolbox;
use smtech\ReflexiveCanvasLTI\LTI\ToolProvider;
use Battis\DataUtilities;
define('CONFIG_FILE', __DIR__ . '/config.xml');
define('CANVAS_INSTANCE_URL', 'canvasInstanceUrl');
@session_start();
// TODO I don't feel good about suppressing warnings
/* prepare the toolbox */
if (empty($_SESSION[Toolbox::class])) {
    $_SESSION[Toolbox::class] =& Toolbox::fromConfiguration(CONFIG_FILE);
}
$toolbox =& $_SESSION[Toolbox::class];
if (php_sapi_name() !== 'cli') {
    $toolbox->smarty_prependTemplateDir(__DIR__ . '/templates', basename(__DIR__));
    $toolbox->smarty_assign(['category' => DataUtilities::titleCase(preg_replace('/[\\-_]+/', ' ', basename(__DIR__)))]);
    $smarty =& $toolbox->getSmarty();
    // FIXME
}
/*
 * FIXME convience variables until plugins are all updated
 */
$api =& $toolbox->getAPI();
$sql =& $toolbox->getMySQL();
$customPrefs =& $toolbox->getCustomPrefs();
/* set the Tool Consumer's instance URL, if present */
if (empty($_SESSION[CANVAS_INSTANCE_URL])) {
    if (!empty($_SESSION[ToolProvider::class]['canvas']['api_domain'])) {
        $_SESSION[CANVAS_INSTANCE_URL] = 'https://' . $_SESSION[ToolProvider::class]['canvas']['api_domain'];
    } else {
        $_SESSION[CANVAS_INSTANCE_URL] = $toolbox->config('TOOL_CANVAS_API')['url'];
Ejemplo n.º 5
0
 /**
  * Update a Toolbox instance from a configuration file
  *
  * @see Toolbox::fromConfiguration() Use `Toolbox::fromConfiguration()`
  *
  * @param  string $configFilePath
  * @param  boolean $forceRecache
  * @return void
  */
 protected function loadConfiguration($configFilePath, $forceRecache = false)
 {
     $logQueue = [];
     /* load the configuration file */
     $config = new ConfigXML($configFilePath);
     /* configure database connections */
     $this->setMySQL($config->newInstanceOf(mysqli::class, '/config/mysql'));
     /* configure metadata caching */
     $id = $config->toString('/config/tool/id');
     if (empty($id)) {
         $id = basename(dirname($configFilePath)) . '_' . md5(__DIR__ . file_get_contents($configFilePath));
         $logQueue[] = "    Automatically generated ID {$id}";
     }
     $this->setMetadata(new AppMetadata($this->mysql, $id, self::TOOL_METADATA_TABLE));
     /* update metadata */
     if ($forceRecache || empty($this->metadata['TOOL_ID']) || empty($this->metadata['TOOL_LAUNCH_URL']) || empty($this->metadata['TOOL_CONFIG_FILE'])) {
         $tool = $config->toArray('/config/tool')[0];
         $this->metadata['TOOL_ID'] = $id;
         $this->metadata['TOOL_NAME'] = empty($tool['name']) ? $id : $tool['name'];
         $this->metadata['TOOL_CONFIG_FILE'] = realpath($configFilePath);
         $configPath = dirname($this->metadata['TOOL_CONFIG_FILE']);
         if (!empty($tool['description'])) {
             $this->metadata['TOOL_DESCRIPTION'] = $tool['description'];
         } elseif (isset($this->metadata['TOOL_DESCRIPTION'])) {
             unset($this->metadata['TOOL_DESCRIPTION']);
         }
         if (!empty($tool['icon'])) {
             $this->metadata['TOOL_ICON_URL'] = file_exists("{$configPath}/{$tool['icon']}") ? DataUtilities::URLfromPath("{$configPath}/{$tool['icon']}") : $tool[self::ICON];
         } elseif (isset($this->metadata['TOOL_ICON_URL'])) {
             unset($this->metadata['TOOL_ICON_URL']);
         }
         $this->metadata['TOOL_LAUNCH_PRIVACY'] = empty($tool['launch-privacy']) ? self::DEFAULT_LAUNCH_PRIVACY : $tool['launch-privacy'];
         if (!empty($tool['domain'])) {
             $this->metadata['TOOL_DOMAIN'] = $tool['domain'];
         } elseif (isset($this->metadata['TOOL_DOMAIN'])) {
             unset($this->metadata['TOOL_DOMAIN']);
         }
         $this->metadata['TOOL_LAUNCH_URL'] = empty($tool['authenticate']) ? DataUtilities::URLfromPath($_SERVER['SCRIPT_FILENAME']) : DataUtilities::URLfromPath("{$configPath}/{$tool['authenticate']}");
         $logQueue[] = "    Tool metadata configured";
     }
     $configPath = dirname($this->metadata['TOOL_CONFIG_FILE']);
     /* configure logging */
     if ($forceRecache || empty($this->metadata['TOOL_LOG'])) {
         $log = "{$configPath}/" . $config->toString('/config/tool/log');
         shell_exec("touch \"{$log}\"");
         $this->metadata['TOOL_LOG'] = realpath($log);
     }
     $this->setLog(Log::singleton('file', $this->metadata['TOOL_LOG']));
     if ($forceRecache) {
         $this->log("Resetting LTI configuration from {$configFilePath}");
     }
     if (!empty($logQueue)) {
         foreach ($logQueue as $message) {
             $this->log($message);
         }
         unset($logQueue);
     }
     /* configure tool provider */
     if ($forceRecache || empty($this->metadata['TOOL_HANDLER_URLS'])) {
         $handlers = $config->toArray('/config/tool/handlers')[0];
         if (empty($handlers) || !is_array($handlers)) {
             throw new ConfigurationException('At least one handler/URL pair must be specified', ConfigurationException::TOOL_PROVIDER);
         }
         foreach ($handlers as $request => $path) {
             $handlers[$request] = DataUtilities::URLfromPath("{$configPath}/{$path}");
         }
         $this->metadata['TOOL_HANDLER_URLS'] = $handlers;
         $this->log('    Tool provider handler URLs configured');
     }
     /* configure API access */
     if ($forceRecache || empty($this->metadata['TOOL_CANVAS_API'])) {
         $this->metadata['TOOL_CANVAS_API'] = $config->toArray('/config/canvas')[0];
         if (empty($this->metadata['TOOL_CANVAS_API'])) {
             throw new ConfigurationException('Canvas API credentials must be provided', ConfigurationException::CANVAS_API_MISSING);
         }
         $this->log('    Canvas API credentials configured');
     }
 }
Ejemplo n.º 6
0
 /**
  * Construct the singleton instance of BootstrapSmarty
  *
  * @deprecated Use singleton pattern BootstrapSmarty::getSmarty()
  *
  * @param string|string[] $template (Optional) Additional Smarty template
  *        directories
  * @param string|string[] $config (Optional) Additional Smarty config
  *        directories
  * @param string $compile (Optional) Alternative Smarty compiled template
  *        directory
  * @param string $cache (Optional) Alternative Smarty cache directory
  *
  * @return void
  *
  * @throws BootstrapSmarty_Exception SINGLETON If an instance of BootstrapSmarty already exists
  *
  * @see BootstrapSmarty::getSmarty() BootstrapSmarty::getSmarty()
  * @see http://www.phptherightway.com/pages/Design-Patterns.html#singleton Singleton Design Pattern
  **/
 public function __construct($template = null, $config = null, $compile = null, $cache = null)
 {
     if (static::$singleton !== null) {
         throw new BootstrapSmarty_Exception('BootstrapSmarty is a singleton class, use the factory method ' . 'BootstrapSmarty::getSmarty() instead of ' . __METHOD__, BootstrapSmarty_Exception::SINGLETON);
     } else {
         parent::__construct();
         static::$singleton = $this;
     }
     /* Default to local directories for use by Smarty */
     $this->setTemplateDir([static::UI_KEY => realpath(__DIR__ . '/../templates')]);
     $this->setConfigDir([static::UI_KEY => realpath(__DIR__ . '/../configs')]);
     /* Apply user additions and alternates */
     if (!empty($template)) {
         $this->prependTemplateDir($template);
     }
     if (!empty($config)) {
         $this->addConfigDir($config);
     }
     $this->setCompileDir(empty($compile) ? realpath(__DIR__ . '/../templates_c') : $compile);
     $this->setCacheDir(empty($cache) ? realpath(__DIR__ . '/../cache') : $cache);
     /* Test all directories for use by Smarty */
     foreach ($this->getTemplateDir() as $key => $dir) {
         static::testAccess($dir);
     }
     foreach ($this->getConfigDir() as $key => $dir) {
         static::testAccess($dir);
     }
     static::testAccess($this->getCompileDir(), true);
     static::testAccess($this->getCacheDir(), true);
     /* set some reasonable defaults */
     $this->url = DataUtilities::URLfromPath(dirname(__DIR__));
     $this->assign('BOOTSTRAPSMARTY_URL', $this->url);
     $this->addStylesheet("{$this->url}/css/BootstrapSmarty.css", static::UI_KEY);
     $this->assign(['name' => DataUtilities::titleCase(preg_replace('/[\\-_]+/', ' ', urldecode(basename($_SERVER['REQUEST_URI'], '.php')))), 'category' => DataUtilities::titleCase(preg_replace('/[\\-_]+/', ' ', urldecode(basename(dirname($_SERVER['REQUEST_URI']))))), 'navbarActive' => false, 'MODULE_COLORPICKER' => static::MODULE_COLORPICKER, 'MODULE_DATEPICKER' => static::MODULE_DATEPICKER, 'MODULE_SORTABLE' => static::MODULE_SORTABLE]);
 }
Ejemplo n.º 7
0
if (!empty($_REQUEST['oauth-return'])) {
    $_SESSION['oauth']['return'] = $_REQUEST['oauth-return'];
}
/* have we been given a specific error URL? */
if (!empty($_REQUEST['oauth-error'])) {
    $_SESSION['oauth']['error'] = $_REQUEST['oauth-error'];
}
/* do we have a Canvas instance URL yet? */
if (empty($_SESSION['oauth']['instance']) && empty($_REQUEST['url'])) {
    $smarty->assign(['formAction' => $_SERVER['PHP_SELF'], 'reason' => empty($_REQUEST['reason']) ? false : $_REQUEST['reason']]);
    $smarty->display('oauth.tpl');
    exit;
} elseif (empty($_SESSION['oauth']['instance']) && !empty($_REQUEST['url'])) {
    $_SESSION['oauth']['instance'] = $_REQUEST['url'];
}
$provider = new CanvasLMS(['clientId' => $_SESSION['oauth']['key'], 'clientSecret' => $_SESSION['oauth']['secret'], 'purpose' => $_SESSION['oauth']['purpose'], 'redirectUri' => DataUtilities::URLfromPath(__FILE__), 'canvasInstanceUrl' => $_SESSION['oauth']['instance']]);
/* if we don't already have an authorization code, let's get one! */
if (!isset($_GET['code'])) {
    $authorizationUrl = $provider->getAuthorizationUrl();
    $_SESSION['oauth']['state'] = $provider->getState();
    header("Location: {$authorizationUrl}");
    exit;
    /* check that the passed state matches the stored state to mitigate cross-site request forgery attacks */
} elseif (empty($_GET['state']) || $_GET['state'] !== $_SESSION['oauth']['state']) {
    unset($_SESSION['oauth']);
    header("Location: {$_SESSION['oauth']['error']}?error[title]=Invalid State&" . 'error[message]=Mismatch between stored and received OAuth states, ' . 'may indicate CSRF attack.');
    exit;
} else {
    /*
     * acquire and save our token (using our existing code), pass back the
     * newly-acquired token in session data
Ejemplo n.º 8
0
                                    </tr>
                                    <?php 
    }
    ?>

                                </table>
                            </td>
                            <?php 
}
?>

                        </tr>
                    </table>

                <div id="link"><a href="<?php 
$shortlink = DataUtilities::URLfromPath(__FILE__) . '?cache=' . $key;
echo $shortlink;
?>
"><?php 
echo $shortlink;
?>
</a></div>

                </div>

                <?php 
if (!$printable) {
    ?>
                    <h2>Enter a note for the bottom of the schedule</h2>
                <?php 
}
Ejemplo n.º 9
0
         unset($source['sis_course_id']);
         unset($source['integration_id']);
         unset($source['name']);
         unset($source['course_code']);
         unset($source['account_id']);
         unset($source['enrollment_term_id']);
         unset($source['start_at']);
         unset($source['end_at']);
         unset($source['enrollments']);
         /* why nest this, I mean... really? */
         $source = array('course' => $source);
     } catch (Exception $e) {
         $toolbox->exceptionErrorMessage($e);
     }
 }
 $csv = DataUtilities::loadCsvToArray('csv');
 if ($csv) {
     $courses = array_merge($courses, $csv);
 }
 if (!empty($courses)) {
     foreach ($courses as $course) {
         /* build parameter list */
         $params = array();
         if (!empty($course['course_id'])) {
             $params['sis_course_id'] = $course['course_id'];
         } else {
             $params['sis_course_id'] = generateSisId(empty($course['course_id']) ? $course['long_name'] : $course['course_id']);
         }
         if (!empty($course['long_name'])) {
             $params['name'] = $course['long_name'];
         }
Ejemplo n.º 10
0
     $sourceName = $source['name'];
     /* clear settings that are provided form entry */
     unset($source['id']);
     unset($source['sis_course_id']);
     unset($source['integration_id']);
     unset($source['name']);
     unset($source['course_code']);
     unset($source['account_id']);
     unset($source['enrollment_term_id']);
     unset($source['start_at']);
     unset($source['end_at']);
     unset($source['enrollments']);
     /* why nest this, I mean... really? */
     $source = array('course' => $source);
 }
 $courses = DataUtilities::loadCsvToArray('csv');
 if ($step == STEP_CONFIRM) {
     if (empty($courses)) {
         $toolbox->smarty_addMessage('Courses', 'No courses found in uploaded list.', NotificationMessage::ERROR);
         $step = STEP_INSTRUCTIONS;
     } else {
         foreach ($courses as $course) {
             /* duplicate course settings */
             $course = $toolbox->api_put("/courses/sis_course_id:{$course['course_id']}", $source);
             // TODO  nice to figure out navigation settings copy
             /* duplicate course content */
             $migration = $toolbox->api_post("courses/{$course['id']}/content_migrations", array('migration_type' => 'course_copy_importer', 'settings[source_course_id]' => $template));
             $toolbox->smarty_addMessage("<a target=\"_parent\" href=\"{$_SESSION[CANVAS_INSTANCE_URL]}/courses/{$course['id']}\">{$course['name']}</a>", "has been templated as a clone of <a target=\"_parent\" href=\"{$_SESSION[CANVAS_INSTANCE_URL]}/courses/{$sourceId}\">{$sourceName}</a>. Course content is being <a target=\"_parent\" href=\"{$_SESSION[CANVAS_INSTANCE_URL]}/courses/{$course['id']}/content_migrations\">migrated</a> right now.", NotificationMessage::GOOD);
         }
     }
 }
Ejemplo n.º 11
0
$advisee = isset($_REQUEST['advisee']) ? $_REQUEST['advisee'] : $advisees[0]['user']['id'];
$toolbox->cache_pushKey($advisee);
$courses = $toolbox->cache_get('courses');
if ($courses === false) {
    $allCourses = $toolbox->api_get("users/{$advisee}/courses");
    $courses = [];
    foreach ($allCourses as $course) {
        if (!empty($course['account_id']) && isAcademic($course['account_id'])) {
            $courses[$course['id']] = $course;
        }
    }
    $toolbox->cache_set('courses', $courses);
}
$analytics = $toolbox->cache_get('analytics');
if ($analytics === false) {
    $analytics = [];
    foreach ($courses as $course) {
        $analytics[$course['id']] = $toolbox->api_get("courses/{$course['id']}/analytics/users/{$advisee}/assignments");
    }
    $toolbox->cache_set('analytics', $analytics);
}
$toolbox->cache_popKey();
$toolbox->cache_popKey();
$toolbox->smarty_assign(['advisee' => $advisee, 'advisees' => $advisees, 'terms' => $terms, 'courses' => $courses, 'analytics' => $analytics, 'canvasInstanceUrl' => $_SESSION[CANVAS_INSTANCE_URL]]);
/*
 * FIXME unclear why the post-bootstrap-scripts block isn't working in the
 *     relative-grades.tpl file
 */
$toolbox->getSmarty()->addScript(DataUtilities::URLfromPath(__DIR__ . '/../vendor/npm-asset/chart.js/dist/Chart.min.js'));
$toolbox->getSmarty()->addScript(DataUtilities::URLfromPath(__DIR__ . '/../js/relative-grades.js.php') . "?advisee={$advisee}");
$toolbox->smarty_display('relative-grades.tpl');
Ejemplo n.º 12
0
 /**
  * Interactively acquire an API access token
  *
  * `/config/canvas/key` and `/config/canvas/secret` must be defined in
  * `config.xml` for this to work!
  *
  * @param string $reason Explanation of why an API access token is necessary
  * @param string $redirectURL (Optional, defaults to
  *     `$_SERVER['REQUEST_URI']`) URL of page to redirect to after
  *     acquiring access token
  * @param string $errorURL (Optional) URL of page to redirect to on error
  * @return void
  */
 public function interactiveGetAccessToken($reason = null, $redirectURL = null, $errorURL = null)
 {
     $redirectURL = empty($redirectURL) ? $_SERVER['REQUEST_URI'] : $redirectURL;
     $errorURL = empty($errorURL) ? DataUtilities::URLfromPath(__DIR__ . '/../error.php') : $errorURL;
     $canvas = $this->metadata['TOOL_CANVAS_API'];
     if (!empty($canvas['key']) && !empty($canvas['secret'])) {
         /* if so, request an API access token interactively */
         if (session_status() !== PHP_SESSION_ACTIVE) {
             session_start();
         }
         $_SESSION['oauth'] = ['purpose' => $this->metadata['TOOL_NAME'], 'key' => $canvas['key'], 'secret' => $canvas['secret']];
         header('Location: ' . DataUtilities::URLfromPath(__DIR__ . '/../oauth.php') . '?' . http_build_query(['oauth-return' => $redirectURL, 'oauth-error' => $errorURL, 'reason' => $reason]));
         break;
     } else {
         /* no (understandable) API credentials available -- doh! */
         throw new ConfigurationException('Missing OAuth key/secret pair in configuration, which is ' . 'required to interactively acquire an API access token', ConfigurationException::CANVAS_API_MISSING);
     }
 }
Ejemplo n.º 13
0
<?php

require_once 'common.inc.php';
use Battis\DataUtilities;
use Battis\BootstrapSmarty\NotificationMessage;
define('STEP_INSTRUCTIONS', 1);
define('STEP_CONFIRM', 2);
define('STEP_UPDATE', 3);
$step = empty($_REQUEST['step']) ? STEP_INSTRUCTIONS : $_REQUEST['step'];
$ignoreCourseId = empty($_REQUEST['ignore_course_id']) ? false : $_REQUEST['ignore_course_id'];
switch ($step) {
    case STEP_CONFIRM:
        $sections = DataUtilities::loadCsvToArray('csv');
        if (empty($sections)) {
            $step = STEP_INSTRUCTIONS;
            $toolbox->smarty_addMessage('Empty section list', 'The uploaded CSV file contained no sections.', NotificationMessage::WARNING);
        }
        if ($step == STEP_CONFIRM) {
            $toolbox->smarty_assign(['fields' => array_keys($sections[0]), 'sections' => $sections, 'formHidden' => ['step' => STEP_UPDATE, 'ignore_course_id' => $ignoreCourseId]]);
            $toolbox->smarty_display(basename(__FILE__, '.php') . '/confirm.tpl');
            break;
        }
        /* flows into STEP_UPDATE */
    /* flows into STEP_UPDATE */
    case STEP_UPDATE:
        if ($step == STEP_UPDATE) {
            $links = [];
            $crosslist = [];
            $crosslistFail = [];
            foreach ($_REQUEST['sections'] as $section) {
                if (isset($section['batch-include']) && $section['batch-include'] == 'include') {
function titleCase($s)
{
    return DataUtilities::titleCase(str_replace('_', ' ', $s));
}