...
 
Commits (76)
......@@ -88,8 +88,10 @@ doc/devtools/check_tiki-new.php -text
doc/devtools/check_tiki.php -text
doc/devtools/cleanwatch.sh -text
doc/devtools/clear_tracker_fast.sql -text
doc/devtools/composer_http_mode.php -text
doc/devtools/convert_templates_prefs-2.0.php -text
doc/devtools/convert_tpl_ajax.php -text
doc/devtools/convert_tracker_attachments.php -text
doc/devtools/csscheck.sh -text
doc/devtools/cssmap.pl -text
doc/devtools/dbdiff/composer.json -text
......@@ -1710,6 +1712,7 @@ installer/schema/20100902_invit_tiki.sql -text
installer/schema/20100903_article_ispublished_tiki.sql -text
installer/schema/20100906_sheet_toolbar_default_tiki.sql -text
installer/schema/20100909_alter_tiki_language_fields_to_text_tiki.sql -text
installer/schema/20100909_ckeditor_upgrade_tiki.sql -text
installer/schema/20100909_lengthen_wiki_attachments_filename_tiki.sql -text
installer/schema/20100910_new_fields_for_tiki_blogs_tiki.sql -text
installer/schema/20100912_rename_autosave_pref_tiki.sql -text
......@@ -1989,6 +1992,8 @@ installer/schema/20171123_create_object_links_tiki.php -text
installer/schema/20171129_backlinks_for_object_types_admin_options_tiki.sql -text
installer/schema/20171130_plugin_include_link_original_tiki.sql -text
installer/schema/20171204_update_geo_enabled_tiki.sql -text
installer/schema/20180405_remove_unused_user_id_tiki.sql -text
installer/schema/20180411_schedulers_change_column_to_text_tiki.sql -text
installer/schema/999999991_decode_pages_sources_tiki.php -text
installer/schema/99999999_image_plugins_kill_tiki.php -text
installer/schema/index.php -text
......@@ -2583,6 +2588,7 @@ lib/core/Search/Formatter/ValueFormatter/Number.php -text
lib/core/Search/Formatter/ValueFormatter/Objectlink.php -text
lib/core/Search/Formatter/ValueFormatter/Plain.php -text
lib/core/Search/Formatter/ValueFormatter/Reference.php -text
lib/core/Search/Formatter/ValueFormatter/Slug.php -text
lib/core/Search/Formatter/ValueFormatter/Snippet.php -text
lib/core/Search/Formatter/ValueFormatter/Sorthandle.php -text
lib/core/Search/Formatter/ValueFormatter/Timeago.php -text
......
......@@ -25,10 +25,8 @@ doc/devtools/dbdiff/vendor
/dummy.php
/dump
/files
img/trackers/*
img/wiki/*.gif
img/wiki/*.pad_xml
img/wiki_up/*
installer/.htaccess
lang/.htaccess
/last.log
......
......@@ -41,6 +41,46 @@ if ($access->ticketMatch()) {
$smarty->assign('diagnostic_composer_output', $composerManager->getComposer()->execDiagnose());
}
}
if ($_POST['remove-composer-locker']) {
$path = $tikipath . DIRECTORY_SEPARATOR . 'composer.lock';
if (file_exists($path)) {
if (is_writable($path)) {
unlink($path);
$smarty->assign('composer_management_success', tr('composer.lock file was removed'));
} else {
$smarty->assign('composer_management_error', tr('composer.lock file is not writable, so it can not be removed')
);
}
} else {
$smarty->assign('composer_management_success', tr('composer.lock file do not exists'));
}
}
if ($_POST['clean-vendor-folder']) {
$dir = $tikipath . DIRECTORY_SEPARATOR . 'vendor/';
if (file_exists($dir)) {
if (is_writable($dir)) {
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS),
RecursiveIteratorIterator::CHILD_FIRST
);
foreach ($files as $file) {
if ($file->getFilename() === '.htaccess') {
continue;
}
if ($file->isDir()) {
rmdir($file->getRealPath());
} else {
unlink($file->getRealPath());
}
}
$smarty->assign('composer_management_success', tr('Vendor folder contents was removed'));
} else {
$smarty->assign('composer_management_error', tr('Vendor folder is not writable'));
}
} else {
$smarty->assign('composer_management_success', tr('Vendor folder do not exists'));
}
}
}
}
......
......@@ -634,8 +634,7 @@ CREATE TABLE `tiki_custom_route` (
`type` varchar(255) NOT NULL,
`from` varchar(255) NOT NULL,
`redirect` text NOT NULL,
`active` tinyint(1) NOT NULL DEFAULT '1',
`user_id` int(11) NOT NULL
`active` tinyint(1) NOT NULL DEFAULT '1'
) ENGINE=MyISAM;
DROP TABLE IF EXISTS `tiki_directory_categories`;
......@@ -4052,7 +4051,7 @@ CREATE TABLE `tiki_scheduler` (
`name` VARCHAR(255),
`description` VARCHAR(255),
`task`VARCHAR(255),
`params` VARCHAR(255),
`params` TEXT,
`run_time` VARCHAR(255),
`status` VARCHAR(10),
`re_run` TINYINT
......
......@@ -5,6 +5,10 @@
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
// $Id$
namespace TikiDevTools;
use DateTime;
/*
* Script to check name convention of schema files
* Available options:
......@@ -170,5 +174,10 @@ class CheckSchemaNamingConvention
}
}
// Make sure script is run from a shell
if (PHP_SAPI !== 'cli') {
die("Please run from a shell");
}
$checker = new CheckSchemaNamingConvention();
$checker->execute();
\ No newline at end of file
$checker->execute();
......@@ -5,6 +5,8 @@
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
// $Id$
namespace TikiDevTools;
/**
* Script to check sql CREATE statements have got DROP IF EXIST in front of it
* Available commands:
......@@ -61,7 +63,7 @@ class CheckSchemaSqlDrop
*
* @return array
*/
function getOpts()
protected function getOpts()
{
$shortOpts = "p:o:f::";
$longOpts = [
......@@ -77,7 +79,7 @@ class CheckSchemaSqlDrop
*
* @return string
*/
function getPath()
protected function getPath()
{
$sqlPath = '../../db/tiki.sql';
$options = $this->getOpts();
......@@ -98,7 +100,7 @@ class CheckSchemaSqlDrop
* @param $path
* @return int
*/
function checkFile($path)
protected function checkFile($path)
{
$sqlFile = file_get_contents($path);
......@@ -157,11 +159,8 @@ class CheckSchemaSqlDrop
for ($i = 0; $i < sizeof($queries) - 1; $i++) {
$curQuery = $queries[$i];
$nextQuery = $queries[$i + 1];
if (strpos($curQuery, "DROP TABLE IF EXISTS") !== false && substr(
$nextQuery,
0,
2
) === (PHP_EOL . PHP_EOL)) {
if (strpos($curQuery, "DROP TABLE IF EXISTS") !== false
&& substr($nextQuery, 0, 2) === (PHP_EOL . PHP_EOL)) {
$queries[++$i] = substr($nextQuery, 1);
}
}
......@@ -182,6 +181,11 @@ class CheckSchemaSqlDrop
}
}
// Make sure script is run from a shell
if (PHP_SAPI !== 'cli') {
die("Please run from a shell");
}
$checker = new CheckSchemaSqlDrop();
$errors = $checker->execute();
if ($errors > 0) {
......
......@@ -5,6 +5,15 @@
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
// $Id$
namespace TikiDevTools;
use DBDiff;
use Exception;
use PDO;
use Symfony\Component\Process\PhpExecutableFinder;
use Symfony\Component\Process\Process;
use TWVersion;
/**
* Class CheckSchemaUpgrade is a helper to check differences between upgrade and install a tiki db
*/
......@@ -125,7 +134,6 @@ class CheckSchemaUpgrade
//
$this->printMessage('Comparing Databases');
$this->runDbCompare();
} catch (\Exception $e) {
$this->printMessageError($e->getMessage());
$resultValue = 1;
......@@ -343,7 +351,7 @@ class CheckSchemaUpgrade
/**
* Loads the a SQL file from a major into Tiki database (so we can run upgrade)
*
* @param $dbConnection
* @param PDO $dbConnection
* @return bool
* @throws Exception
*/
......@@ -404,10 +412,8 @@ class CheckSchemaUpgrade
}
$dbContent = file_get_contents(sprintf(self::DB_URL_TEMPLATE, $major));
if (! empty($dbContent) && strpos(
$dbContent,
'CREATE TABLE `tiki_schema`'
) !== false) { //check that looks like a sql file
/** @noinspection SyntaxError */
if (! empty($dbContent) && strpos($dbContent, 'CREATE TABLE `tiki_schema`') !== false) { //check that looks like a sql file
$sql = $dbContent;
file_put_contents($cachedDbFile, $dbContent);
return $sql;
......@@ -461,9 +467,9 @@ class CheckSchemaUpgrade
*/
protected function runDatabaseUpdate()
{
$phpFinder = new \Symfony\Component\Process\PhpExecutableFinder();
$phpFinder = new PhpExecutableFinder();
$process = new \Symfony\Component\Process\Process(
$process = new Process(
[
$phpFinder->find(),
'console.php',
......@@ -489,9 +495,9 @@ class CheckSchemaUpgrade
*/
protected function runDatabaseInstall()
{
$phpFinder = new \Symfony\Component\Process\PhpExecutableFinder();
$phpFinder = new PhpExecutableFinder();
$process = new \Symfony\Component\Process\Process(
$process = new Process(
[
$phpFinder->find(),
'console.php',
......@@ -540,12 +546,12 @@ class CheckSchemaUpgrade
// set a well defined date for some records
$dbConnection->exec("UPDATE `tiki_schema` SET `install_date` = '2001-01-01 01:01:01'");
// remove cache clean messages from action log
$dbConnection->exec("DELETE FROM `tiki_actionlog` WHERE `comment` = 'erased all cache content'");
// remove messages from action log (are not part of the schema)
$dbConnection->exec("DELETE FROM `tiki_actionlog`");
}
/**
* Execute the DB comparation between the instance that was upgraded and the instance that did the clean install
* Execute the DB comparision between the instance that was upgraded and the instance that did the clean install
*
* @throws Exception
*/
......@@ -617,10 +623,9 @@ class CheckSchemaUpgrade
$result = array_filter(
$parts,
function ($item) {
if (
strncmp($item, 'DELETE FROM `tiki_preferences`', 30) === 0
|| strncmp($item, 'INSERT INTO `tiki_preferences`', 30) === 0
) {
/** @noinspection SyntaxError */
if (strncmp($item, 'DELETE FROM `tiki_preferences`', 30) === 0
|| strncmp($item, 'INSERT INTO `tiki_preferences`', 30) === 0) {
return false;
}
return true;
......@@ -660,7 +665,7 @@ class CheckSchemaUpgrade
/**
* Get the options from command line
*/
function getOpts()
protected function getOpts()
{
$shortOpts = 'm:vp';
$longOpts = [
......@@ -683,7 +688,7 @@ class CheckSchemaUpgrade
* @param null $long
* @return null
*/
function getOption($options, $short = null, $long = null)
protected function getOption($options, $short = null, $long = null)
{
if (! empty($long) && array_key_exists($long, $options)) {
return $options[$long];
......@@ -697,6 +702,11 @@ class CheckSchemaUpgrade
}
}
// Make sure script is run from a shell
if (PHP_SAPI !== 'cli') {
die("Please run from a shell");
}
$checker = new CheckSchemaUpgrade();
$errors = $checker->execute();
if ($errors > 0) {
......
......@@ -5,6 +5,8 @@
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
// $Id$
namespace TikiDevTools;
/**
* Script to check sql CREATE statements used MyISAM engine in ../../db/tiki.sql and ../../installer/schema sql files
*
......@@ -171,6 +173,11 @@ class CheckSqlEngine
}
}
// Make sure script is run from a shell
if (PHP_SAPI !== 'cli') {
die("Please run from a shell");
}
$checker = new CheckSqlEngine();
$errorCount = $checker->execute();
......@@ -178,5 +185,3 @@ if ($errorCount > 0) {
exit(1);
}
exit(0);
#!/usr/bin/php
<?php
// (c) Copyright 2002-2018 by authors of the Tiki Wiki CMS Groupware Project
//
// All Rights Reserved. See copyright.txt for details and a complete list of authors.
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
// $Id$
if (isset($_SERVER['REQUEST_METHOD'])) {
die('Only available through command-line.');
}
$tikiBase = realpath(dirname(__FILE__) . '/../..');
$composerJsonFile = "$tikiBase/vendor_bundled/composer.json";
$composerJsonFileBackup = str_replace('/composer.', '/composer_https.', $composerJsonFile);
$composerLockFile = "$tikiBase/vendor_bundled/composer.lock";
$composerLockFileBackup = str_replace('/composer.', '/composer_https.', $composerLockFile);
if ($_SERVER['argc'] <= 1 || isset($_SERVER['argv']['help'])) {
echo 'Changes composer files to use http only for use behind firewalls etc.
Options:
execute : Change composer to use http mode
revert : Revert changes to use normal https mode
';
return;
} else if ($_SERVER['argv'][1] === 'revert') {
revert();
} else if ($_SERVER['argv'][1] === 'execute') {
execute();
}
function execute()
{
global $tikiBase, $composerJsonFile, $composerJsonFileBackup, $composerLockFile, $composerLockFileBackup;
$repoUrlHttps = 'https://composer.tiki.org';
$repoUrlHttp = 'http://composer.tiki.org';
if (! is_writable("$tikiBase/vendor_bundled/") || ! is_writable($composerJsonFile) || ! is_writable($composerLockFile)) {
echo "Error: Cannot write to $tikiBase/vendor_bundled/ or the composer files\n";
return;
}
echo "Backing up original files\n";
// back up both files
if (! file_exists($composerJsonFileBackup)) {
copy($composerJsonFile, $composerJsonFileBackup);
} else {
echo "Error: composer.json backup file already exists\n";
return;
}
if (! file_exists($composerLockFileBackup)) {
copy($composerLockFile, $composerLockFileBackup);
} else {
echo "Error: composer.lock backup file already exists\n";
return;
}
echo "Processing composer.json\n";
$json = json_decode(file_get_contents($composerJsonFile), true);
$json['config']['secure-http'] = false;
$json['repositories'][0]['url'] = str_replace($repoUrlHttps, $repoUrlHttp, $json['repositories'][0]['url']);
file_put_contents($composerJsonFile, json_encode($json, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
echo "Processing composer.lock\n";
$lock = file_get_contents($composerLockFile);
$lock = str_replace($repoUrlHttps, $repoUrlHttp, $lock);
file_put_contents($composerLockFile, $lock);
echo "Done\n";
}
function revert()
{
global $tikiBase, $composerJsonFile, $composerJsonFileBackup, $composerLockFile, $composerLockFileBackup;
if (! is_writable("$tikiBase/vendor_bundled/") || ! is_writable($composerJsonFile) || ! is_writable($composerLockFile)) {
echo "Error: Cannot write to $tikiBase/vendor_bundled/ or the composer files\n";
return;
}
// check for back files
if (! file_exists($composerJsonFileBackup)) {
echo "Error: composer.json backup file not found\n";
return;
}
if (! file_exists($composerLockFileBackup)) {
echo "Error: composer.lock backup file not found\n";
return;
}
echo "Restoring backup files\n";
unlink($composerJsonFile);
rename($composerJsonFileBackup, $composerJsonFile);
unlink($composerLockFile);
rename($composerLockFileBackup, $composerLockFile);
echo "Done\n";
}
\ No newline at end of file
#!/usr/bin/php
<?php
// (c) Copyright 2002-2018 by authors of the Tiki Wiki CMS Groupware Project
//
// All Rights Reserved. See copyright.txt for details and a complete list of authors.
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
// $Id$
if ($argc < 3) {
$helpMsg = "\nUsage: php doc/devtools/convert_tracker_attachments.php trackerId fieldId [fileGalId] ['remove']\n";
$helpMsg .= "\nExamples: \n\t\tphp doc/devtools/convert_tracker_attachments.php 1 2";
$helpMsg .= "\n\t\tphp doc/devtools/convert_tracker_attachments.php 1 2 2\n\n";
exit($helpMsg);
}
require_once('tiki-setup.php');
$context = new Perms_Context("admin");
$trackerId = $argv[1];
$fieldId = $argv[2];
if (! isset($trackerId)) {
echo "Error: Missing trackerId\n";
exit(1);
}
if (! isset($fieldId)) {
echo "Error: Missing fieldId\n";
exit(1);
}
if (isset($argv[3])) {
$galleryId = $argv[3];
} else {
$galleryId = 0;
}
if (isset($argv[4]) && $argv[4] === 'remove') {
$remove = true;
} else {
$remove = false;
}
/**
* @param $trackerId
* @param $fieldId
* @param int $galleryId
* @throws Services_Exception
* @throws Exception
*/
function convertAttachments($trackerId, $fieldId, $galleryId = 0, $remove = false)
{
global $prefs;
$trklib = TikiLib::lib('trk');
$trackerUtilities = new Services_Tracker_Utilities;
$definition = Tracker_Definition::get($trackerId);
// Check if tracker and fieldId are valid
$fgField = $trackerUtilities->getFieldsFromIds($definition, [$fieldId]);
if (! $fgField || $fgField[0]['type'] !== 'FG') {
echo "Error: Invalid fieldId {$fieldId} for trackerId {$trackerId}\n";
exit(1);
}
$fgField = $fgField[0];
if (! $galleryId && isset($fgField['options_map']['galleryId'])) {
$galleryId = $fgField['options_map']['galleryId'];
}
if (! $galleryId) {
$galleryId = $prefs['fgal_root_id'];
}
// Check if its a valid file gallery
try {
$fileUtilities = new Services_File_Utilities;
$galInfo = $fileUtilities->checkTargetGallery($galleryId);
} catch (Services_Exception $e) {
echo "Error: {$e->getMessage()}\n";
exit(1);
}
$items = $trackerUtilities->getItems(['trackerId' => $trackerId]);
$failedAttIds = [];
$itemsFailed = 0;
$itemsProcessed = 0;
$attachmentsProcessed = 0;
foreach ($items as $item) {
$itemId = $item['itemId'];
$itemObject = Tracker_Item::fromId($itemId);
if (! $itemObject || $itemObject->getDefinition() !== $definition) {
continue;
}
$atts = $trklib->list_item_attachments($itemId, 0, -1, 'comment_asc', '');
$fileIdList = [];
$numAttachments = sizeof($atts['data']);
if ($numAttachments === 0) {
echo "Tracker Item {$itemId} skipped (no attachments)\n";
continue;
} else {
echo "Updating tracker item {$itemId}:\n";
$ess = $numAttachments > 1 ? 's' : '';
echo "- Found {$numAttachments} attachment$ess\n";
}
foreach ($atts['data'] as $attachment) {
$attachment = $trklib->get_item_attachment($attachment['attId']);
if (! $attachment) {
echo "- Warning: Unable to get item attachment with attId {$attachment['attId']}\n";
continue;
}
$name = $attachment['filename'];
$size = $attachment['filesize'];
$type = $attachment['filetype'];
$description = $attachment['longdesc'];
if ($attachment['comment']) {
$description .= "\nComment\n" . $attachment['comment'];
}
$data = $attachment['data'];
try {
$fileId = $fileUtilities->uploadFile($galInfo, $name, $size, $type, $data, null, null, null, $description);
} catch (Exception $e) {
$fileId = false;
echo "Error: File {$attachment['filename']} on item {$itemId} could not be saved\n";
echo "{$e->getMessage()}\n";
}
if ($fileId !== false) {
array_push($fileIdList, $fileId);
echo "- Attachment {$attachment['filename']} uploaded to file gallery\n";
} else {
echo "- Failed to upload attachment {$attachment['filename']} to file gallery\n";
$failedAttIds[] = $attachment['attId'];
}
}
if (empty($fileIdList)) {
echo "No files were uploaded to the file gallery\n";
echo "Tracker Item {$itemId} skipped\n";
continue;
}
$input = new JitFilter([
'trackerId' => $trackerId,
'itemId' => $itemId,
]);
$processedFields = $itemObject->prepareInput($input);
$fields = [];
foreach ($processedFields as $key => $field) {
$permName = $field['permName'];
$fields[$permName] = isset($field['value']) ? $field['value'] : '';
if ($field['fieldId'] == $fieldId && $field['type'] == 'FG') {
$fields[$permName] = empty($fields[$permName]) ? implode(',', $fileIdList) : $fields[$permName] . ',' . implode(',', $fileIdList);
}
}
$result = $trackerUtilities->updateItem(
$definition,
[
'itemId' => $itemId,
'status' => '',
'fields' => $fields,
]
);
if ($result !== false) {
$itemsProcessed++;
if ($remove) {
foreach ($atts['data'] as $attachment) {
if (! in_array($attachment['attId'], $failedAttIds)) {
$trklib->remove_item_attachment($attachment['attId'], $itemId);
$attachmentsProcessed++;
} else {
echo "(Attachment {$attachment['attId']} {$attachment['filename']} not removed)\n";
$numAttachments--;
}
}
echo "Tracker item {$itemId} updated successfully and $numAttachments attachment$ess removed\n";
} else {
$attachmentsProcessed += $numAttachments;
echo "Tracker item {$itemId} updated successfully\n";
}
} else {
echo "Tracker item {$itemId} update failed\n";
$itemsFailed++;
}
}
$failCount = count($failedAttIds);
$op = $remove ? "moved" : "copied";
echo "\nConvert completed:\n {$itemsProcessed} processed ({$itemsFailed} failed) and\n {$attachmentsProcessed} attachments {$op} ({$failCount} failed)\n\n";
}
convertAttachments($trackerId, $fieldId, $galleryId, $remove);
exit(0);
......@@ -324,6 +324,9 @@ class SvnUpCommand extends Command
$endRev = ' unknown';
}
$raw = shell_exec('svn cleanup 2>&1');
$output->writeln($raw, OutputInterface::VERBOSITY_DEBUG);
if (! $input->getOption('no-db')) {
$progress->setMessage('Clearing all caches');
$progress->advance();
......
-- Revert file removal in svn r64512, so that upgrading a existing DB and a clean install generate same output
ALTER TABLE tiki_custom_route DROP COLUMN `user_id`;
ALTER TABLE `tiki_scheduler` CHANGE `params` `params` TEXT;
\ No newline at end of file
......@@ -295,16 +295,18 @@ class RelationLib extends TikiDb_Bridge
}
/**
* Remove all relations from that type.
* Remove all relations from that type and source items belonging to that tracker
* @param $relation - the relation type
* @param $trackerId - the tracker id
*/
public function remove_relation_type($relation)
public function remove_relation_type($relation, $trackerId)
{
return $this->table->deleteMultiple(
[
'relation' => $relation,
]
);
return $this->query("DELETE FROM tiki_object_relations
WHERE relation = ?
AND source_type = 'trackeritem'
AND source_itemId IN(
SELECT itemId FROM tiki_tracker_items WHERE trackerId = ?
)", [$relation, $trackerId]);
}
/**
......@@ -322,7 +324,6 @@ class RelationLib extends TikiDb_Bridge
'source_itemId' => $fromId
]
);
$this->remove_relation_type($relationType);
}
/**
......
......@@ -119,6 +119,8 @@ class Item
{
global $tikilib;
switch ($this->type) {
case 'Direct':
if ($path === $this->from) {
......@@ -148,7 +150,9 @@ class Item
require_once('tiki-sefurl.php');
$smarty = TikiLib::lib('smarty');
$smarty->loadPlugin('smarty_modifier_sefurl');
$isExternal = TikiLib::setExternalContext(true);
$url = smarty_modifier_sefurl($objectId, $type);
TikiLib::setExternalContext($isExternal);
return $url;
}
......@@ -174,7 +178,14 @@ class Item
return false;
}
return 'item' . $itemId;
require_once('tiki-sefurl.php');
$smarty = TikiLib::lib('smarty');
$smarty->loadPlugin('smarty_modifier_sefurl');
$isExternal = TikiLib::setExternalContext(true);
$url = smarty_modifier_sefurl($itemId, 'trackeritem');
TikiLib::setExternalContext($isExternal);
return $url;
break;
default:
......
......@@ -45,7 +45,7 @@ class H5P_H5PTiki implements H5PFrameworkInterface
self::$h5p_path = 'storage/public';
if ($this->getOption('cron_last_run') < time() - 86400) {
if ($this->getOption('cron_last_run') < time() - 86400 && ! empty($_SERVER['HTTP_HOST'])) {
// Cron not run in >24h, trigger it
// Determine full URL
......
......@@ -18,7 +18,9 @@ class Math_Formula_Function_Sub extends Math_Formula_Function
$out = array_shift($elements);
foreach ($elements as $element) {
$out -= $element;
if (is_numeric($element)) {
$out -= $element;
}
}
return $out;
......
......@@ -107,11 +107,12 @@ class Search_Elastic_Index implements Search_Index_Interface, Search_Index_Query
return [
"type" => $this->connection->getVersion() >= 5 ? "keyword" : "string",
"index" => $this->connection->getVersion() >= 5 ? true : "not_analyzed",
"ignore_above" => 32765,
"fields" => [
"sort" => $this->connection->getVersion() >= 5 ?
[
"type" => "keyword",
"ignore_above" => 200,
"ignore_above" => 1000,
] : [
"type" => "string",
"analyzer" => "sortable",
......@@ -161,9 +162,9 @@ class Search_Elastic_Index implements Search_Index_Interface, Search_Index_Query
"fields" => [
"sort" => $this->connection->getVersion() >= 5 ?
[
"type" => "text",
"analyzer" => "sortable",
"fielddata" => true,
"type" => "keyword",
"ignore_above" => 1000,
"normalizer" => "sortable",
] : [
"type" => "string",
"analyzer" => "sortable",
......@@ -210,6 +211,13 @@ class Search_Elastic_Index implements Search_Index_Interface, Search_Index_Query
'filter' => ['lowercase', 'asciifolding'],
],
],
'normalizer' => [
'sortable' => [
'type' => 'custom',
'char_filter' => [],
'filter' => ['lowercase', 'asciifolding']
],
],
'filter' => [
'tiki_stop' => [
'type' => 'stop',
......
......@@ -138,7 +138,7 @@ class Search_Elastic_QueryBuilder
} elseif ($node instanceof Initial) {
return [
'match_phrase_prefix' => [
$this->getNodeField($node) . '.sort' => [
$this->getNodeField($node) => [
"query" => $this->getTerm($node),
"boost" => $node->getWeight(),
],
......
<?php
// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
//
// All Rights Reserved. See copyright.txt for details and a complete list of authors.
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
// $Id$
class Search_Formatter_ValueFormatter_Slug extends Search_Formatter_ValueFormatter_Abstract
{
private $manager = null;
function __construct($arguments)
{
$this->manager = TikiLib::lib('slugmanager');
}
function render($name, $value, array $entry)
{
global $prefs;
$slug = $this->manager->generate($prefs['wiki_url_scheme'], $value, $prefs['url_only_ascii'] === 'y');
return $slug;
}
}
......@@ -18,7 +18,7 @@ class Search_Formatter_ValueFormatter_Timeago extends Search_Formatter_ValueForm
$value = date_create_from_format('YmdHise', $value . 'UTC')->getTimestamp();
}
if ($prefs['jquery_timeago'] === 'y') {
if ($prefs['jquery_timeago'] === 'y' && $value) {
TikiLib::lib('header')->add_jq_onready('$("time.timeago").timeago();');
return '<time class="timeago" datetime="' . TikiLib::date_format('c', $value, false, 5, false) . '">' . $value . '</time>';
} else {
......
......@@ -23,8 +23,56 @@ class Search_Indexer
{
if (! $logWriter instanceof \Zend\Log\Writer\AbstractWriter) {
$logWriter = new Zend\Log\Writer\Noop();
} else {
// writing logs
set_error_handler(function ($errno, $errstr, $errfile = '', $errline = 0) {
$error = '';
switch ($errno) {
case E_PARSE:
case E_ERROR:
case E_CORE_ERROR:
case E_COMPILE_ERROR:
case E_USER_ERROR:
$error = 'FATAL';
break;
case E_WARNING:
case E_USER_WARNING:
case E_COMPILE_WARNING:
case E_RECOVERABLE_ERROR:
$error = 'WARNING';
break;
case E_NOTICE:
case E_USER_NOTICE:
$error = 'NOTICE';
break;
case E_STRICT:
$error = 'STRICT';
break;
case E_DEPRECATED:
case E_USER_DEPRECATED:
$error = 'DEPRECATED';
break;
default :
break;
}
$this->log->err($error . ': ' . $errstr, [
'code' => $errno,
'file' => $errfile,
'line' => $errline,
]);
return [$error, $errstr];
});
// set smarty error muting again after declaring our handler becasue smarty is set up in tiki-setup.php
// before we get here so smarty then doesn't know about us
Smarty_Tiki::muteExpectedErrors();
}
$logWriter->setFormatter(new Zend\Log\Formatter\Simple(Zend\Log\Formatter\Simple::DEFAULT_FORMAT . ' [%memoryUsage% bytes]' . PHP_EOL));
$logWriter->setFormatter(new Zend\Log\Formatter\Simple());
$this->log = new Zend\Log\Logger();
$this->log->addWriter($logWriter);
......@@ -285,6 +333,6 @@ class Search_Indexer
private function log($message)
{
$this->log->info($message, ['memoryUsage' => memory_get_usage()]);
$this->log->info($message, ['memoryUsage' => \Symfony\Component\Console\Helper\Helper::formatMemory(memory_get_usage())]);
}
}
......@@ -21,9 +21,41 @@ class Services_File_Controller
$this->utilities = new Services_File_Utilities;
}
/**
* Call to prepare the upload in modal dialg, and then after the upload has happened
* Here we add a description if that's enabled
*
* @param JitFilter $input
* @return array
* @throws Exception
*/
function action_uploader($input)
{
$gal_info = $this->checkTargetGallery($input);
$filegallib = TikiLib::lib('filegal');
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if ($input->offsetExists('description')) {
$files = $input->asArray('file');
$descriptions = $input->asArray('description');
foreach ($files as $c => $file) {
$fileInfo = $filegallib->get_file_info($file);
if (isset($descriptions[$c])) {
$filegallib->update_file(
$fileInfo['fileId'],
$fileInfo['filename'],
$descriptions[$c],
$fileInfo['asuser']
);
}
}
}
}
return [
'title' => tr('File Upload'),
......@@ -33,21 +65,25 @@ class Services_File_Controller
'uploadInModal' => $input->uploadInModal->int(),
'files' => $this->getFilesInfo((array) $input->file->int()),
'image_max_size_x' => $input->image_max_size_x->text(),
'image_max_size_y' => $input->image_max_size_y->text()
'image_max_size_y' => $input->image_max_size_y->text(),
'addDecriptionOnUpload' => $input->addDecriptionOnUpload->int(),
];
}
function action_upload($input)
{
if ($input->files->asArray()) {
return;
return [];
}
$gal_info = $this->checkTargetGallery($input);
$fileId = $input->fileId->int();
$asuser = $input->user->text();
if (empty($asuser)) {
$asuser = $GLOBALS['user'];
}
if (! $input->imagesize->word()) {
$image_x = $input->image_max_size_x->text();
$image_y = $input->image_max_size_y->text();
......
......@@ -36,10 +36,10 @@ class Services_File_Utilities
return $filegallib->get_file_gallery_info($galleryId);
}
function uploadFile($gal_info, $name, $size, $type, $data, $asuser = null, $image_x = null, $image_y = null)
function uploadFile($gal_info, $name, $size, $type, $data, $asuser = null, $image_x = null, $image_y = null, $description = '')
{
$filegallib = TikiLib::lib('filegal');
return $filegallib->upload_single_file($gal_info, $name, $size, $type, $data, $asuser, $image_x, $image_y);
return $filegallib->upload_single_file($gal_info, $name, $size, $type, $data, $asuser, $image_x, $image_y, $description);
}
function updateFile($gal_info, $name, $size, $type, $data, $fileId, $asuser = null)
......
......@@ -97,7 +97,7 @@ class Services_Scheduler_Controller
$logger
);
$message = tr('Running scheduler %0', $schedulerTask->name) . '<br>';
$message = tr('Execution output:') . '<br><br>';
$result = $schedulerTask->execute();
if ($result['status'] == 'failed') {
......@@ -108,6 +108,7 @@ class Services_Scheduler_Controller
}
return [
'title' => tr('Running %0', $schedulerTask->name),
'schedulerId' => $schedulerId,
'name' => $scheduler['name'],
'message' => $message,
......
......@@ -39,7 +39,7 @@ class Services_Search_Controller
$memory_limiter = new Tiki_MemoryLimit($prefs['allocate_memory_unified_rebuild']);
}
$stat = $unifiedsearchlib->rebuild(isset($_REQUEST['loggit']));
$stat = $unifiedsearchlib->rebuild($input->loggit->int());
TikiLib::lib('cache')->empty_type_cache('search_valueformatter');
......@@ -67,6 +67,8 @@ class Services_Search_Controller
'memory_peak_usage_before' => FormatterHelper::formatMemory($memory_peak_usage_before),
'memory_peak_usage_after' => FormatterHelper::formatMemory(memory_get_peak_usage()),
'num_queries' => ($num_queries_after - $num_queries_before),
'log_file_browser' => $unifiedsearchlib->getLogFilename(1),
'log_file_console' => $unifiedsearchlib->getLogFilename(2),
];
}
......
......@@ -35,8 +35,6 @@ class Table_Code_MainOptions extends Table_Code_Manager
/*** onRenderHeader option - change html elements before table renders. Repeated for each column. ***/
$orh = [];
/*** Headers ***/
$headers = [];
/* First handle column-specific code since the array index is used for the column number */
foreach (parent::$s['columns'] as $col => $info) {
//turn off column resizing per settings
......@@ -116,7 +114,6 @@ class Table_Code_MainOptions extends Table_Code_Manager
$orh[$col] .= '.' . $attr . '(\'' . $args . '\')';
}
$orh[$col] .= ';}';
$headers[] = "'$col': { filter: 'text', sorter: 'text' }";
}
unset($col, $info);
}
......@@ -138,15 +135,13 @@ class Table_Code_MainOptions extends Table_Code_Manager
}
/*** end onRenderHeader section ***/
/*** headers ***/
if (count($headers) > 0) {
$mo[] = $this->iterate($headers, 'headers: {', '}', '', '', ', ', ', ' );
}
/*** widgets ***/
//standard ones
$w[] = 'stickyHeaders';
$w[] = 'sort2Hash';
//sort2Hash doesn't work with ajax yet
if (! parent::$ajax) {
$w[] = 'sort2Hash';
}
//only fancytable uses this and it is set in wikiplugin_fancytable.php
//other tables don't show up full width due to use of table-responsive class in wrapper div
if (isset(parent::$s['resizable']) && parent::$s['resizable']) {
......
......@@ -64,7 +64,11 @@ class IndexRebuildCommand extends Command
}
if (! $cron) {
$output->writeln('Started rebuilding index...');
$message = '[' . \TikiLib::lib('tiki')->get_short_datetime(0) . '] Started rebuilding index...';
if ($log) {
$message .= ' logging to file: ' . $unifiedsearchlib->getLogFilename($log);
}
$output->writeln($message);
}
if (! $cron) {
......
......@@ -414,6 +414,34 @@ class CleanVendors
'Python',
]
);
self::removeMultiple($vendors . 'plotly/plotly.js/',
[
'src',
'dist/extras',
'dist/topojson',
'dist/plotly.js',
'dist/plotly.min.js',
'dist/plot-schema.json',
'dist/plotly-basic.js',
'dist/plotly-basic.min.js',
'dist/plotly-cartesian.js',
'dist/plotly-finance.js',
'dist/plotly-finance.min.js',
'dist/plotly-geo-assets.js',
'dist/plotly-geo.js',
'dist/plotly-geo.min.js',
'dist/plotly-gl2d.js',
'dist/plotly-gl2d.min.js',
'dist/plotly-gl3d.js',
'dist/plotly-gl3d.min.js',
'dist/plotly-mapbox.js',
'dist/plotly-mapbox.min.js',
'dist/plotly-with-meta.js',
'dist/translation-keys.txt',
'dist/plotly-locale-*'
]
);
}
private static function addIndexFile($path)
......
......@@ -247,7 +247,7 @@ class ComposerCli
$args = [$args];
}
$output = $errors = '';
$command = $output = $errors = '';
try {
$builder = new ProcessBuilder();
......@@ -268,6 +268,8 @@ class ComposerCli
$process = $builder->getProcess();
$command = $process->getCommandLine();
$process->setTimeout($this->timeout);
$process->run();
......@@ -282,7 +284,7 @@ class ComposerCli
}
$this->lastResult = [
'command' => $process->getCommandLine(),
'command' => $command,
'output' => $output,
'errors' => $errors,
'code' => $code
......
......@@ -169,6 +169,9 @@ class Tracker_Field_DateTime extends Tracker_Field_Abstract implements Tracker_F
function getDocumentPart(Search_Type_Factory_Interface $typeFactory)
{
if ($this->getValue() && (strlen($this->getValue()) > 10 || intval($this->getValue()) <= 0)) {
trigger_error("Possibly incorrect timestamp value found when trying to send to search index. Tracker item ".$this->getItemId().", field ".$this->getConfiguration('permName').", value ".$this->getValue(), E_USER_WARNING);
}
$baseKey = $this->getBaseKey();
return [
$baseKey => $typeFactory->timestamp($this->getValue(), $this->getOption('datetime') == 'd'),
......
......@@ -241,31 +241,49 @@ $("input[name=ins_' . $filterFieldIdHere . '], select[name=ins_' . $filterFieldI
//$listFieldThere = array_merge($listFieldThere, array('value' => $remoteItemId));
$handler = $trklib->get_field_handler($listFieldThere, $itemInfo);
// array selected_categories etc.
$valueField = $handler->getFieldData();
if ($handler) {
$valueField = $handler->getFieldData();
} else {
Feedback::error(tr('DynamicList field: Field "%0" not found', $listFieldThere['permName']));
}
// for some reason, need to apply the values back, otherwise renderOutput does not return a value - bug or intended?