diff --git a/.gitignore b/.gitignore index d9734d08..108b66b9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ engine/templates_c/* -engine/include/vendor +vendor config/config.local.php docker/www/config/config.local.php secured_data/ccls diff --git a/composer.json b/composer.json index d6471e1b..749087dc 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,5 @@ { "config": { - "platform": {"php":"5.6"}, - "vendor-dir": "engine/include/vendor" }, "autoload": { @@ -17,7 +15,7 @@ "classmap": [ "engine/external/pear/", "engine/include/", - "engine/config/", + "engine/Config/", "engine/page/", "engine/external/ChromePhp.php", "phpunit/classes" @@ -43,12 +41,11 @@ }, "require": { "ext-json": "*", - "ext-zip": "*", - "ext-gd": "*" + "ext-zip": "*" }, "require-dev": { - "phpunit/phpunit": "4.8.", - "phpunit/dbunit": "1.4.*", + "firephp/firephp-core": "^0.5.3", + "phpunit/phpunit": "^4.8", "mikey179/vfsstream": "^1.6" } } diff --git a/database/README.md b/database/README.md new file mode 100644 index 00000000..ab2b35d8 --- /dev/null +++ b/database/README.md @@ -0,0 +1,4 @@ +### Database Initialization +Before you start first time database docker move inforex-v1.0.sql to init/ folder + +File removed form init/ folder to prevent accidental initialization. diff --git a/database/init/inforex-v1.0.sql b/database/inforex-v1.0.sql similarity index 99% rename from database/init/inforex-v1.0.sql rename to database/inforex-v1.0.sql index c45af4ec..20113c55 100644 --- a/database/init/inforex-v1.0.sql +++ b/database/inforex-v1.0.sql @@ -1614,7 +1614,7 @@ DROP TABLE IF EXISTS `tasks`; CREATE TABLE `tasks` ( `task_id` int(11) NOT NULL AUTO_INCREMENT, `datetime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Data i czas utworzenia zadania.', - `datetime_start` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `datetime_start` timestamp NULL DEFAULT NULL, `type` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'Identyfikator zadania.', `description` text COLLATE utf8mb4_unicode_ci, `parameters` text COLLATE utf8mb4_unicode_ci NOT NULL, @@ -1988,7 +1988,6 @@ UNLOCK TABLES; /*!50001 SET character_set_results = utf8 */; /*!50001 SET collation_connection = utf8_general_ci */; /*!50001 CREATE ALGORITHM=UNDEFINED */ -/*!50013 DEFINER=`gpw`@`localhost` SQL SECURITY DEFINER */ /*!50001 VIEW `activities_view_users` AS select `u`.`screename` AS `screename`,count(0) AS `COUNT(*)`,max(`a`.`datetime`) AS `last_datetime`,`a`.`activity_page_id` AS `activity_page_id`,`a`.`datetime` AS `datetime`,`a`.`ip_id` AS `ip_id`,`a`.`user_id` AS `user_id`,`a`.`corpus_id` AS `corpus_id`,`a`.`report_id` AS `report_id`,`a`.`activity_type_id` AS `activity_type_id`,`a`.`execution_time` AS `execution_time` from (`activities` `a` join `users` `u` on((`a`.`user_id` = `u`.`user_id`))) group by `a`.`user_id` */; /*!50001 SET character_set_client = @saved_cs_client */; /*!50001 SET character_set_results = @saved_cs_results */; @@ -2006,7 +2005,6 @@ UNLOCK TABLES; /*!50001 SET character_set_results = utf8 */; /*!50001 SET collation_connection = utf8_general_ci */; /*!50001 CREATE ALGORITHM=UNDEFINED */ -/*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */ /*!50001 VIEW `reports_annotations` AS select `ra`.`id` AS `id`,`ra`.`report_id` AS `report_id`,`ra`.`type_id` AS `type_id`,`at`.`name` AS `type`,`ra`.`from` AS `from`,`ra`.`to` AS `to`,`ra`.`text` AS `text`,`ra`.`user_id` AS `user_id`,`ra`.`creation_time` AS `creation_time`,`ra`.`stage` AS `stage`,`ra`.`source` AS `source` from (`reports_annotations_optimized` `ra` left join `annotation_types` `at` on((`at`.`annotation_type_id` = `ra`.`type_id`))) */; /*!50001 SET character_set_client = @saved_cs_client */; /*!50001 SET character_set_results = @saved_cs_results */; @@ -2024,7 +2022,6 @@ UNLOCK TABLES; /*!50001 SET character_set_results = utf8 */; /*!50001 SET collation_connection = utf8_general_ci */; /*!50001 CREATE ALGORITHM=UNDEFINED */ -/*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */ /*!50001 VIEW `tokens_tags` AS select `tt`.`token_tag_id` AS `token_tag_id`,`tt`.`token_id` AS `token_id`,`b`.`text` AS `base`,`tt`.`base_id` AS `base_id`,`tokens_tags_ctags`.`ctag` AS `ctag`,`tt`.`disamb` AS `disamb` from ((`tokens_tags_optimized` `tt` left join `bases` `b` on((`b`.`id` = `tt`.`base_id`))) left join `tokens_tags_ctags` on((`tt`.`ctag_id` = `tokens_tags_ctags`.`id`))) */; /*!50001 SET character_set_client = @saved_cs_client */; /*!50001 SET character_set_results = @saved_cs_results */; diff --git a/database/queries/annotations_delete_by_corpus_id_and_stage.sql b/database/queries/annotations_delete_by_corpus_id_and_stage.sql deleted file mode 100644 index a005f269..00000000 --- a/database/queries/annotations_delete_by_corpus_id_and_stage.sql +++ /dev/null @@ -1,3 +0,0 @@ -SET @corpus_id=51; -SET @stage='new'; -DELETE an FROM `reports_annotations_optimized` an JOIN reports r ON (an.report_id=r.id) WHERE r.corpora=@corpus_id AND an.stage=@stage; \ No newline at end of file diff --git a/database/update/update_001_user_activities.sql b/database/update/update_001_user_activities.sql deleted file mode 100644 index 7f18eec4..00000000 --- a/database/update/update_001_user_activities.sql +++ /dev/null @@ -1,10 +0,0 @@ -CREATE TABLE `gpw`.`user_activities` ( -`user_id` INT NOT NULL , -`started` DATETIME NOT NULL , -`ended` DATETIME NOT NULL , -`counter` INT NOT NULL , -INDEX ( `user_id` , `ended` ) -) ENGINE = MYISAM ; - -ALTER TABLE `user_activities` ADD `login` BOOLEAN NOT NULL ; -ALTER TABLE `user_activities` ADD `id` BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST ; diff --git a/database/update/update_002_report_perspective.sql b/database/update/update_002_report_perspective.sql deleted file mode 100644 index 0efd08b9..00000000 --- a/database/update/update_002_report_perspective.sql +++ /dev/null @@ -1,62 +0,0 @@ --- --- Struktura tabeli dla `corpus_and_report_perspectives` --- - -CREATE TABLE IF NOT EXISTS `corpus_and_report_perspectives` ( - `perspective_id` varchar(32) NOT NULL, - `corpus_id` int(11) NOT NULL, - `access` enum('public','loggedin','role') NOT NULL, - PRIMARY KEY (`perspective_id`,`corpus_id`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; - --- --- Zrzut danych tabeli `corpus_and_report_perspectives` --- - -INSERT INTO `corpus_and_report_perspectives` (`perspective_id`, `corpus_id`, `access`) VALUES -('transcription', 3, 'public'), -('preview', 1, 'public'), -('html', 1, 'public'), -('report', 1, 'public'), -('takipi', 1, 'public'), -('edit', 1, 'loggedin'), -('edit_raw', 1, 'loggedin'), -('annotator', 1, 'loggedin'), -('tei', 1, 'public'), -('preview', 5, 'public'), -('html', 5, 'public'), -('report', 5, 'public'), -('takipi', 5, 'public'), -('edit', 5, 'loggedin'), -('edit_raw', 5, 'loggedin'), -('annotator', 5, 'loggedin'), -('tei', 5, 'public'); - --- -------------------------------------------------------- - --- --- Struktura tabeli dla `report_perspectives` --- - -CREATE TABLE IF NOT EXISTS `report_perspectives` ( - `id` varchar(32) NOT NULL, - `title` varchar(255) NOT NULL, - `order` int(11) NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; - --- --- Zrzut danych tabeli `report_perspectives` --- - -INSERT INTO `report_perspectives` (`id`, `title`, `order`) VALUES -('transcription', 'Transcription', 10), -('preview', 'Text', 20), -('html', 'HTML', 30), -('raw', 'Źródłowy dokument', 40), -('takipi', 'TaKIPI', 50), -('edit', 'Edycja', 60), -('edit_raw', 'Edycja / źródło', 70), -('annotator', 'Anotacja', 80), -('tei', 'TEI', 90); - diff --git a/database/update/update_003_images.sql b/database/update/update_003_images.sql deleted file mode 100644 index c9c4ea3f..00000000 --- a/database/update/update_003_images.sql +++ /dev/null @@ -1,13 +0,0 @@ -CREATE TABLE `images` ( - `id` BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY , - `corpus_id` INT NOT NULL, - `original_name` VARCHAR(64) NOT NULL , - `hash_name` VARCHAR(32) NOT NULL -) ; - -CREATE TABLE `reports_and_images` ( - `report_id` INT NOT NULL , - `images_id` INT NOT NULL , - `position` INT NOT NULL , - PRIMARY KEY ( `report_id` , `images_id` ) -) ; \ No newline at end of file diff --git a/database/update/update_004_relation_types.sql b/database/update/update_004_relation_types.sql deleted file mode 100644 index 1ab22b11..00000000 --- a/database/update/update_004_relation_types.sql +++ /dev/null @@ -1,36 +0,0 @@ -/* -Tabela typów relacji powinna zawierać: - - * identyfikator relacji (może być liczba, auto increment), - * nazwa relacji, do 64 znaków, - * opis relacji, text, - * identyfikator kategorii (z tabeli annotation_sets) --- informaja, między jakimi typami jednostek będzie można tworzyć relacje. -*/ -CREATE TABLE `relation_types` ( - `id` INT NOT NULL AUTO_INCREMENT, - `name` VARCHAR(64) NOT NULL, - `description` TEXT NOT NULL, - `annotation_set_id` INT NOT NULL, - PRIMARY KEY (`id`) -); - - -/* -Tabela instancji relacji powinna zawierać: - - * identyfikator instancji (liczba, auto increment), - * identyfikator typu relacji (z powyższej tabeli), - * jednostka źródłowa (identyfikator jednostki, z tabeli report_annotations), - * jednostka docelowa (j/w), - * data dodania, - * identyfikator użytkownika, który dodał relację. -*/ -CREATE TABLE `relations` ( - `id` BIGINT(20) NOT NULL AUTO_INCREMENT, - `relation_type_id` INT NOT NULL, - `source_id` BIGINT(20) NOT NULL, - `target_id` BIGINT(20) NOT NULL, - `date` DATE NOT NULL, - `user_id` INT NOT NULL, - PRIMARY KEY (`id`) -); \ No newline at end of file diff --git a/database/update/update_005_events.sql b/database/update/update_005_events.sql deleted file mode 100644 index 4bc9634d..00000000 --- a/database/update/update_005_events.sql +++ /dev/null @@ -1,83 +0,0 @@ -/*Grupy zdarzeń -event_groups -* event_group_id INT KEY AUTO_INREMENT -* name VARCHAR(64) -* description TEXT -*/ -CREATE TABLE `event_groups` ( - `event_group_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , - `name` VARCHAR( 64 ) NOT NULL , - `description` TEXT NOT NULL -); - -/*Typy zdarzeń przypisane do grup: -event_types -* event_type_id INT KEY AUTO_INREMENT -* name VARCHAR(64) -* description TEXT -* event_group_id INT -*/ -CREATE TABLE `event_types` ( - `event_type_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , - `name` VARCHAR( 64 ) NOT NULL , - `description` TEXT NOT NULL , - `event_group_id` INT NOT NULL -); - -/*Typy slotów przypisane do typów zdarzeń: - -event_type_slots -* event_type_slot INT KEY AUTO_INCREMENT -* name VARCHAR(64) -* description TEXT -* event_type_id INT*/ -CREATE TABLE `event_type_slots` ( - `event_type_slot_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , - `name` VARCHAR( 64 ) NOT NULL , - `description` TEXT NOT NULL , - `event_type_id` INT NOT NULL -); - - - -/*Przypisanie grup zdarzeń do korpusów: -corpus_event_groups -* corpus_id INT -* event_group_id INT*/ -CREATE TABLE `corpus_event_groups` ( - `corpus_id` INT NOT NULL, - `event_group_id` INT NOT NULL -); - -/*Instancje zdarzeń: - -reports_events -* report_event_id INT KEY AUTO_INCREMENT -* report_id INT -* event_type_id INT -* user_id INT -* creation_time DATETIME*/ -CREATE TABLE `reports_events` ( - `report_event_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , - `report_id` INT NOT NULL , - `event_type_id` INT NOT NULL , - `user_id` INT NOT NULL , - `creation_time` DATETIME NOT NULL -); - - -/*Sloty instancji zdarzenia: -reports_events_slots -* report_event_slot_id INT KEY AUTO_INCREMENT -* report_event_id INT -* report_annotation_id INT*/ -CREATE TABLE `reports_events_slots` ( - `report_event_slot_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , - `report_event_id` INT NOT NULL , - `report_annotation_id` INT NULL, - `event_type_slot_id` INT NOT NULL, - `user_id` INT NOT NULL, - `creation_time` DATETIME NOT NULL, - `user_update_id` INT NOT NULL, - `update_time` DATETIME NOT NULL -); diff --git a/database/update/update_006_reports_annotations.sql b/database/update/update_006_reports_annotations.sql deleted file mode 100644 index e3da3045..00000000 --- a/database/update/update_006_reports_annotations.sql +++ /dev/null @@ -1,17 +0,0 @@ -/* -Dodanie pola `user_id` dla `report_annotation_attribute` -Należy dodać pole `user_id` do tabeli `report_annotation_attribute` jako klucz obcy do tabeli `users`. Pole ustawiane jest TYLKO przy utworzeniu atrybutu i wartość pola równa jest identyfikatorowi użytkownika, który dodał pole. Edycja nie zmienia wartości tego pola. - -Klucz dla tej tabeli powinien być zmieniony z (annotation_id, annotation_attribute_id) na (annotation_id, annotation_attribute_id, user_id) -*/ -ALTER TABLE `reports_annotations_attributes` ADD `user_id` INT(11) NOT NULL ; -ALTER TABLE `reports_annotations_attributes` ADD CONSTRAINT `user_id` FOREIGN KEY ( `user_id` ) REFERENCES `users` ( `user_id` ) ; -ALTER TABLE `reports_annotations_attributes` DROP PRIMARY KEY; -ALTER TABLE `reports_annotations_attributes` ADD PRIMARY KEY ( `annotation_id` , `annotation_attribute_id` , `user_id` ); - -/* -Pole `stage` w tabeli `report_annotations` będzie polem wyliczeniowym przyjmującym jedną z wartości: candidate, user, final. -Domyślną wartością jest `user`. -*/ -ALTER TABLE `reports_annotations` ADD `stage` ENUM( 'candidate', 'user', 'final' ) NOT NULL DEFAULT 'user'; - diff --git a/database/update/update_007_annotation_types.sql b/database/update/update_007_annotation_types.sql deleted file mode 100644 index c0e61bbe..00000000 --- a/database/update/update_007_annotation_types.sql +++ /dev/null @@ -1,2 +0,0 @@ -/*Kolumna `short_description` typu VARCHAR będzie zawierała skrócony opis typu anotacji.*/ -ALTER TABLE `annotation_types` ADD `short_description` VARCHAR( 64 ) NULL DEFAULT NULL ; \ No newline at end of file diff --git a/database/update/update_008_tokens.sql b/database/update/update_008_tokens.sql deleted file mode 100644 index ff7fa1b9..00000000 --- a/database/update/update_008_tokens.sql +++ /dev/null @@ -1,19 +0,0 @@ -/*Tabela `tokens` definiuje segmentację tekstu na tokeny. Jeżeli dla danego dokumentu została zdefiniowana segmentacja, to anotacje muszą być spójne z określoną segmentacją. - -tokens -* token_id BIGINT -* report_id INT FOREIGN KEY na reports.id -* from INT -* to INT -*/ -CREATE TABLE `tokens` ( - `token_id` BIGINT (20) NOT NULL AUTO_INCREMENT, - `report_id` BIGINT(20) NOT NULL, - `from` INT NOT NULL, - `to` INT NOT NULL, - PRIMARY KEY (`token_id`), - CONSTRAINT `fk_report_id` FOREIGN KEY (`report_id`) - REFERENCES `reports` (`id`) - ON UPDATE CASCADE -) -ENGINE = InnoDB; diff --git a/database/update/update_009_annotation_types.sql b/database/update/update_009_annotation_types.sql deleted file mode 100644 index 0477675b..00000000 --- a/database/update/update_009_annotation_types.sql +++ /dev/null @@ -1,3 +0,0 @@ -/*Do tabeli anotacji należy dodać pole `css`, w którym będą przechowywany styl anotacji (tło, czcionka, ramka, etc.). -Może to być pole typu VARCHAR, w którym będzie przchowywany opis css.*/ -ALTER TABLE `annotation_types` ADD `css` VARCHAR( 255 ) NULL; \ No newline at end of file diff --git a/database/update/update_010_corpus_perspective_roles.sql b/database/update/update_010_corpus_perspective_roles.sql deleted file mode 100644 index 2c6bddff..00000000 --- a/database/update/update_010_corpus_perspective_roles.sql +++ /dev/null @@ -1,27 +0,0 @@ -/* -Jako trzeci typ dostępu do perspektywy będzie `role`. Oznacza to, że perspektywa będzie dostępna wybranym użytkownikom. Do przechowania informacji o dostępie do perspektywy w trybie `role` będzie trzeba utworzyć tablicę: -corpus_perspective_roles - - * user_id - * corpus_id - * report_perspective_id - -Wpis w tej tablicy będzie oznaczał, że użytkownik user_id ma dostęp do perspektywy report_perspective_id w korpusie corpus_id. - -Jeżeli użytkownik nie będzie miał dostępu do perspektywy, to nie powinna być ona widoczna w menu perspektyw. -*/ -CREATE TABLE `corpus_perspective_roles` ( - `user_id` INT NOT NULL, - `corpus_id` INT NOT NULL, - `report_perspective_id` VARCHAR(32) NOT NULL, - CONSTRAINT `fk_user_id` FOREIGN KEY (`user_id`) - REFERENCES `users` (`user_id`) - ON UPDATE CASCADE, - CONSTRAINT `fk_corpus_id` FOREIGN KEY (`corpus_id`) - REFERENCES `corpora` (`id`) - ON UPDATE CASCADE, - CONSTRAINT `fk_report_perspective_id` FOREIGN KEY (`report_perspective_id`) - REFERENCES `report_perspectives` (`id`) - ON UPDATE CASCADE -) -ENGINE = InnoDB; \ No newline at end of file diff --git a/database/update/update_011_report_perspectives.sql b/database/update/update_011_report_perspectives.sql deleted file mode 100644 index e75fd9ad..00000000 --- a/database/update/update_011_report_perspectives.sql +++ /dev/null @@ -1,9 +0,0 @@ -/*Dodać perspektywę dokumentu o nazwie Tokenization.*/ -INSERT INTO `report_perspectives` ( -`id` , -`title` , -`order` -) -VALUES ( -'tokenization', 'Tokenization', '100' -); \ No newline at end of file diff --git a/database/update/update_012_corpus_subcorpora.sql b/database/update/update_012_corpus_subcorpora.sql deleted file mode 100644 index fa4e54a7..00000000 --- a/database/update/update_012_corpus_subcorpora.sql +++ /dev/null @@ -1,24 +0,0 @@ -/*Dodać tabelę*/ - -CREATE TABLE `corpus_subcorpora` ( - `subcorpus_id` INT NULL AUTO_INCREMENT, - `corpus_id` INT NOT NULL, - `name` VARCHAR( 256 ) NOT NULL , - `description` TEXT NOT NULL , - PRIMARY KEY ( `subcorpus_id` ) -) ENGINE = InnoDB; - - -/*Rozszerzyć schemat tabeli `reports` o kolumnę `subcorpus_id`.*/ -ALTER TABLE `reports` ADD `subcorpus_id` INT NULL; - -/*tymczasowo nie ustawialem kluczy obcych!*/ - -ALTER TABLE `reports` ADD CONSTRAINT `fk_subcorpus_id` FOREIGN KEY (`subcorpus_id`) REFERENCES `corpus_subcorpora` (`subcorpus_id`) ON UPDATE CASCADE; - -ALTER TABLE `corpus_subcorpora` ADD INDEX ( `corpus_id` ) ; - -ALTER TABLE `corpus_subcorpora` ADD FOREIGN KEY ( `corpus_id` ) REFERENCES `gpw`.`corpora` ( -`id` -) ON DELETE CASCADE ON UPDATE CASCADE ; - diff --git a/database/update/update_013_flags.sql b/database/update/update_013_flags.sql deleted file mode 100644 index 6613af13..00000000 --- a/database/update/update_013_flags.sql +++ /dev/null @@ -1,69 +0,0 @@ -/*W bazie należy dodać tabelę, która będzie definicją możliwych statusów postępu prac. - -flags - flag_id INT AUTO_INCREMENT - name VARCHAR(64) - description TEXT - - CREATE TABLE `corpus_perspective_roles` ( - `user_id` INT NOT NULL, - `corpus_id` INT NOT NULL, - `report_perspective_id` VARCHAR(32) NOT NULL, - CONSTRAINT `fk_user_id` FOREIGN KEY (`user_id`) - REFERENCES `users` (`user_id`) - ON UPDATE CASCADE, - CONSTRAINT `fk_corpus_id` FOREIGN KEY (`corpus_id`) - REFERENCES `corpora` (`id`) - ON UPDATE CASCADE, - CONSTRAINT `fk_report_perspective_id` FOREIGN KEY (`report_perspective_id`) - REFERENCES `report_perspectives` (`id`) - ON UPDATE CASCADE -) - - - */ - -CREATE TABLE `flags` ( - `flag_id` INT NOT NULL AUTO_INCREMENT , - `name` VARCHAR( 64 ) NOT NULL , - `description` TEXT NOT NULL , - PRIMARY KEY ( `flag_id` ) -) ENGINE = InnoDB; - -CREATE TABLE `corpora_flags` ( - `corpora_flag_id` INT NOT NULL AUTO_INCREMENT , - `corpora_id` INT NOT NULL , - `name` VARCHAR( 128 ) NOT NULL , - PRIMARY KEY (`corpora_flag_id`) , - CONSTRAINT `fk_corpora_id` FOREIGN KEY (`corpora_id`) - REFERENCES `corpora` (`id`) -) ENGINE = InnoDB; - -CREATE TABLE `reports_flags` ( - `corpora_flag_id` INT NOT NULL, - `report_id` BIGINT(20) NOT NULL, - `flag_id` INT NOT NULL, - CONSTRAINT `fk_corpora_flag_id` FOREIGN KEY (`corpora_flag_id`) - REFERENCES `corpora_flags` (`corpora_flag_id`), - CONSTRAINT `fk1_report_id` FOREIGN KEY (`report_id`) - REFERENCES `reports` (`id`), - CONSTRAINT `fk_flag_id` FOREIGN KEY (`flag_id`) - REFERENCES `flags` (`flag_id`) -) ENGINE = InnoDB; - -INSERT INTO `gpw`.`flags` ( -`flag_id` , -`name` , -`description` -) -VALUES ( -1 , 'nowy', 'dokument nie został jeszcze sprawdzony' -), ( -2 , 'w opracowaniu', 'dokument jest w trakcie opracowania' -), ( -3 , 'gotowy', 'praca nad dokumentem została zakończone i wymaga sprawdzenia' -), ( -4 , 'sprawdzony', 'dokument został pomyślnie sprawdzony' -), ( -5 , 'do poprawy', 'dokument wymaga poprawy' -); diff --git a/database/update/update_014_flags.sql b/database/update/update_014_flags.sql deleted file mode 100644 index a8b4f2e6..00000000 --- a/database/update/update_014_flags.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `reports_flags` ADD UNIQUE `corpora_flag_id_unique` ( `corpora_flag_id` , `report_id` ) \ No newline at end of file diff --git a/database/update/update_015_report_perspectives.sql b/database/update/update_015_report_perspectives.sql deleted file mode 100644 index 41eb45e8..00000000 --- a/database/update/update_015_report_perspectives.sql +++ /dev/null @@ -1,8 +0,0 @@ -INSERT INTO `report_perspectives` ( -`id` , -`title` , -`order` -) -VALUES ( -'autoextension', 'Automatic Extension', '110' -); \ No newline at end of file diff --git a/database/update/update_016_tokens_tags.sql b/database/update/update_016_tokens_tags.sql deleted file mode 100644 index 1d28e9a6..00000000 --- a/database/update/update_016_tokens_tags.sql +++ /dev/null @@ -1,13 +0,0 @@ -CREATE TABLE `tokens_tags` ( - `token_tag_id` BIGINT( 20 ) NOT NULL AUTO_INCREMENT , - `token_id` BIGINT( 20 ) NOT NULL , - `base` VARCHAR( 32 ) NOT NULL , - `ctag` VARCHAR( 32 ) NOT NULL , - `disamb` BOOLEAN NOT NULL , - PRIMARY KEY ( `token_tag_id` ) , - CONSTRAINT `fk_token_id` FOREIGN KEY (`token_id`) - REFERENCES `tokens` (`token_id`) - ON UPDATE CASCADE - ON DELETE CASCADE -) ENGINE = InnoDB; - diff --git a/database/update/update_017_reports_annotations.sql b/database/update/update_017_reports_annotations.sql deleted file mode 100644 index 22fe9747..00000000 --- a/database/update/update_017_reports_annotations.sql +++ /dev/null @@ -1,7 +0,0 @@ -ALTER TABLE `reports_annotations` ADD `source` ENUM( 'user', 'bootstrapping' ) NOT NULL DEFAULT 'user'; -UPDATE `reports_annotations` SET `source` = "user" WHERE `stage` = "user"; -UPDATE `reports_annotations` SET `source` = "bootstrapping" WHERE `stage` = "candidate"; -ALTER TABLE `reports_annotations` CHANGE `stage` `stage` ENUM( 'new', 'final', 'discarded' ) NOT NULL DEFAULT 'final'; -UPDATE `reports_annotations` SET `stage` = "final" WHERE `source` = "user"; -UPDATE `reports_annotations` SET `stage` = "new" WHERE `source` = "bootstrapping"; -UPDATE `report_perspectives` SET `title` = 'Annotation Bootstrapping' WHERE `report_perspectives`.`id` = 'autoextension'; \ No newline at end of file diff --git a/database/update/update_018_relations.sql b/database/update/update_018_relations.sql deleted file mode 100644 index 1fb52994..00000000 --- a/database/update/update_018_relations.sql +++ /dev/null @@ -1,4 +0,0 @@ -ALTER TABLE `relations` DROP FOREIGN KEY `relations_ibfk_2`; -ALTER TABLE `relations` ADD CONSTRAINT `relations_ibfk_2` FOREIGN KEY (`source_id`) REFERENCES `reports_annotations` (`id`) ON DELETE CASCADE; -ALTER TABLE `relations` DROP FOREIGN KEY `relations_ibfk_3`; -ALTER TABLE `relations` ADD CONSTRAINT `relations_ibfk_3` FOREIGN KEY (`target_id`) REFERENCES `reports_annotations` (`id`) ON DELETE CASCADE; \ No newline at end of file diff --git a/database/update/update_019_relations_groups.sql b/database/update/update_019_relations_groups.sql deleted file mode 100644 index f1cdbcf4..00000000 --- a/database/update/update_019_relations_groups.sql +++ /dev/null @@ -1,13 +0,0 @@ -CREATE TABLE `relations_groups` ( - `relation_type_id` int(11) NOT NULL, - `part` enum('source','target') NOT NULL, - `annotation_set_id` int(11) DEFAULT NULL, - `annotation_subset_id` int(11) DEFAULT NULL, - KEY `relation_type_id` (`relation_type_id`), - KEY `annotation_set_id` (`annotation_set_id`), - KEY `annotation_subset_id` (`annotation_subset_id`) -) ENGINE=InnoDB; - -ALTER TABLE `relations_groups` ADD FOREIGN KEY ( `relation_type_id` ) REFERENCES `relation_types` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ; -ALTER TABLE `relations_groups` ADD FOREIGN KEY ( `annotation_set_id` ) REFERENCES `annotation_sets` (`annotation_set_id`) ON DELETE CASCADE ON UPDATE CASCADE ; -ALTER TABLE `relations_groups` ADD FOREIGN KEY ( `annotation_subset_id` ) REFERENCES `annotation_subsets` (`annotation_subset_id`) ON DELETE CASCADE ON UPDATE CASCADE ; \ No newline at end of file diff --git a/database/update/update_020_tokens.sql b/database/update/update_020_tokens.sql deleted file mode 100644 index 2a7cdbc5..00000000 --- a/database/update/update_020_tokens.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `tokens` ADD `eos` BOOLEAN NOT NULL; \ No newline at end of file diff --git a/database/update/update_021_tokens_tags.sql b/database/update/update_021_tokens_tags.sql deleted file mode 100644 index 256cb443..00000000 --- a/database/update/update_021_tokens_tags.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE `tokens_tags` CHANGE `base` `base` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL; -ALTER TABLE `tokens_tags` CHANGE `ctag` `ctag` VARCHAR( 100 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL; diff --git a/database/update/update_022_reports_diffs.sql b/database/update/update_022_reports_diffs.sql deleted file mode 100644 index 5ac3e10e..00000000 --- a/database/update/update_022_reports_diffs.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `reports_diffs` ADD `comment` TEXT NULL ; diff --git a/database/update/update_023_reports_groups.sql b/database/update/update_023_reports_groups.sql deleted file mode 100644 index bc9ee4e8..00000000 --- a/database/update/update_023_reports_groups.sql +++ /dev/null @@ -1 +0,0 @@ -INSERT INTO relations_groups (relation_type_id, part, annotation_set_id) SELECT "1" AS relation_type_id, "source" AS part, annotation_set_id FROM annotation_sets UNION SELECT "1" AS relation_type_id, "target" AS part, annotation_set_id FROM annotation_sets; diff --git a/database/update/update_024_flags_sort.sql b/database/update/update_024_flags_sort.sql deleted file mode 100644 index 3040d27c..00000000 --- a/database/update/update_024_flags_sort.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE `corpora_flags` ADD `short` VARCHAR( 16 ) NOT NULL , -ADD `sort` INT NOT NULL diff --git a/database/update/update_025_statuses.sql b/database/update/update_025_statuses.sql deleted file mode 100644 index 11d862e5..00000000 --- a/database/update/update_025_statuses.sql +++ /dev/null @@ -1,9 +0,0 @@ -INSERT INTO `gpw`.`reports_statuses` ( -`id` , -`status` , -`description` , -`order` -) -VALUES ( -NULL , 'Do usunięcia', 'Dokument powinien zostać usunięty', '8' -); diff --git a/database/update/update_026_reports_tokenization.sql b/database/update/update_026_reports_tokenization.sql deleted file mode 100644 index 874faf0c..00000000 --- a/database/update/update_026_reports_tokenization.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `reports` ADD `tokenization` VARCHAR( 32 ) NOT NULL ; diff --git a/database/update/update_027_common_types.sql b/database/update/update_027_common_types.sql deleted file mode 100644 index 4cc71c0c..00000000 --- a/database/update/update_027_common_types.sql +++ /dev/null @@ -1,29 +0,0 @@ -CREATE TABLE IF NOT EXISTS `annotation_types_common` ( - `annotation_name` varchar(32) NOT NULL, - KEY `annotation_name` (`annotation_name`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - --- --- Dumping data for table `annotation_types_common` --- - -INSERT INTO `annotation_types_common` (`annotation_name`) VALUES -('admin1_nam'), -('admin2_nam'), -('admin3_nam'), -('award_nam'), -('brand_nam'), -('city_nam'), -('country_nam'), -('event_nam'), -('facility_nam'), -('historical_region_nam'), -('institution_nam'), -('nation_nam'), -('organization_nam'), -('person_add_nam'), -('person_first_nam'), -('person_last_nam'), -('person_nam'), -('road_nam'), -('title_nam'); diff --git a/database/update/update_028_reports_ext_kpwr.sql b/database/update/update_028_reports_ext_kpwr.sql deleted file mode 100644 index 4fd7f21b..00000000 --- a/database/update/update_028_reports_ext_kpwr.sql +++ /dev/null @@ -1,9 +0,0 @@ -CREATE TABLE `gpw`.`reports_ext_kpwr` ( -`id` BIGINT NOT NULL , -`keywords` TEXT NOT NULL , -PRIMARY KEY ( `report_id` ) -) ENGINE = InnoDB; - -ALTER TABLE `reports_ext_kpwr` ADD FOREIGN KEY ( `id` ) REFERENCES `gpw`.`reports` ( -`id` -) ON DELETE CASCADE ON UPDATE CASCADE ; diff --git a/database/update/update_029_reports_types.sql b/database/update/update_029_reports_types.sql deleted file mode 100644 index 8b2e0c8a..00000000 --- a/database/update/update_029_reports_types.sql +++ /dev/null @@ -1,32 +0,0 @@ -SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; -SET time_zone = "+00:00"; - - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; - -CREATE TABLE IF NOT EXISTS `reports_formats` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `format` varchar(32) NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ; - - -INSERT INTO `reports_formats` (`id`, `format`) VALUES -(1, 'xml'), -(2, 'plain'), -(3, 'premorph'); - - -ALTER TABLE `reports` ADD `format_id` INT NOT NULL DEFAULT '1'; -ALTER TABLE `reports` ADD INDEX ( `format_id` ) ; - -ALTER TABLE `reports` ADD FOREIGN KEY ( `format_id` ) REFERENCES `inforex`.`reports_formats` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT ; - -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; - - diff --git a/database/update/update_030_1_bases.sql b/database/update/update_030_1_bases.sql deleted file mode 100644 index 507172ed..00000000 --- a/database/update/update_030_1_bases.sql +++ /dev/null @@ -1,56 +0,0 @@ -CREATE TABLE `bases` ( - `id` BIGINT(20) NOT NULL AUTO_INCREMENT, - `text` VARCHAR(255) NOT NULL COLLATE 'utf8_bin', - PRIMARY KEY (`id`), - UNIQUE INDEX `text` (`text`) -) -COLLATE='utf8_bin' -ENGINE=InnoDB; - -INSERT IGNORE INTO bases (text) -SELECT base FROM tokens_tags GROUP BY HEX(base); - -ALTER TABLE `tokens_tags` - ADD COLUMN `base_id` BIGINT(20) NOT NULL AFTER `token_id`; - -SET @count = 0; -UPDATE `bases` SET `bases`.`id` = @count:= @count + 1; -ALTER TABLE bases AUTO_INCREMENT = 1; -UPDATE tokens_tags SET base_id = (SELECT id FROM bases WHERE text=tokens_tags.base COLLATE utf8_bin) WHERE base_id = 0; - -RENAME TABLE `tokens_tags` TO `tokens_tags_optimized`; -ALTER TABLE `tokens_tags_optimized` - ADD CONSTRAINT `FK_tokens_tags_optimized_bases` FOREIGN KEY (`base_id`) REFERENCES `bases` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT; - -ALTER TABLE `tokens_tags_optimized` - DROP COLUMN `base`; - -CREATE ALGORITHM = UNDEFINED VIEW `tokens_tags` AS - SELECT token_tag_id,token_id,b.text as base,base_id,ctag,disamb - FROM tokens_tags_optimized AS tt - LEFT JOIN bases AS b ON b.id=tt.base_id; - -DELIMITER $$ -CREATE PROCEDURE `bases_delete_unused_bases`() - LANGUAGE SQL - NOT DETERMINISTIC - MODIFIES SQL DATA - SQL SECURITY INVOKER - COMMENT '' -BEGIN - DROP TABLE IF EXISTS bases_temp; - - CREATE TEMPORARY TABLE bases_temp ( `base_id` BIGINT NOT NULL, - PRIMARY KEY (`base_id`)) ENGINE=MEMORY; - - INSERT INTO bases_temp (base_id) - SELECT base_id - FROM tokens_tags_optimized - GROUP BY base_id; - - DELETE - FROM bases - WHERE id NOT IN (SELECT * FROM bases_temp); - DROP TABLE bases_temp; -END$$ -DELIMITER $$ diff --git a/database/update/update_030_2_reports_annotations.sql b/database/update/update_030_2_reports_annotations.sql deleted file mode 100644 index 0d65f561..00000000 --- a/database/update/update_030_2_reports_annotations.sql +++ /dev/null @@ -1,26 +0,0 @@ -ALTER TABLE `annotation_types` - ADD COLUMN `annotation_type_id` INT NOT NULL AUTO_INCREMENT FIRST, - ADD PRIMARY KEY (`annotation_type_id`); - -ALTER TABLE `reports_annotations` - ADD COLUMN `type_id` INT(11) NULL DEFAULT NULL AFTER `type`; - -ALTER TABLE `reports_annotations` - DROP FOREIGN KEY `reports_annotations_ibfk_1`; - -UPDATE reports_annotations -SET type_id = (SELECT annotation_type_id FROM annotation_types WHERE annotation_types.name=reports_annotations.type COLLATE utf8_bin); - -ALTER TABLE `reports_annotations` - DROP COLUMN `type`; - -ALTER TABLE `reports_annotations` - ADD CONSTRAINT `FK_annotations_types` FOREIGN KEY (`type_id`) REFERENCES `annotation_types` (`annotation_type_id`) ON UPDATE CASCADE ON DELETE CASCADE; - -RENAME TABLE `reports_annotations` TO `reports_annotations_optimized`; - -CREATE ALGORITHM = UNDEFINED VIEW `reports_annotations` AS - SELECT ra.id, report_id, type_id, at.name AS type, `from`, `to`, text, user_id, creation_time, stage, source - FROM reports_annotations_optimized AS ra - LEFT JOIN annotation_types AS at ON at.annotation_type_id=ra.type_id - \ No newline at end of file diff --git a/database/update/update_030_reports_annotation_lemma.sql b/database/update/update_030_reports_annotation_lemma.sql deleted file mode 100644 index 33fb52a6..00000000 --- a/database/update/update_030_reports_annotation_lemma.sql +++ /dev/null @@ -1,40 +0,0 @@ -INSERT INTO `report_perspectives` (`id`, `title`, `description`, `order`) VALUES ('annotation_lemma', 'Annotation Lemmas', '', '15'); - --- phpMyAdmin SQL Dump --- version 4.0.5deb1 --- http://www.phpmyadmin.net --- --- Host: localhost --- Generation Time: Sep 06, 2013 at 02:36 PM --- Server version: 5.5.32-0ubuntu3 --- PHP Version: 5.5.3-1ubuntu1 - -SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; -SET time_zone = "+00:00"; - --- --- Database: `inforex` --- - --- -------------------------------------------------------- - --- --- Table structure for table `reports_annotations_lemma` --- - -CREATE TABLE IF NOT EXISTS `reports_annotations_lemma` ( - `report_annotation_id` bigint(20) NOT NULL, - `lemma` mediumtext COLLATE utf8_polish_ci NOT NULL, - UNIQUE KEY `report_annotation_id` (`report_annotation_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci; - --- --- Constraints for dumped tables --- - --- --- Constraints for table `reports_annotations_lemma` --- -ALTER TABLE `reports_annotations_lemma` - ADD CONSTRAINT `reports_annotations_lemma_ibfk_1` FOREIGN KEY (`report_annotation_id`) REFERENCES `reports_annotations_optimized` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION; - diff --git a/database/update/update_031_tokens_tags_ctags_pos.sql b/database/update/update_031_tokens_tags_ctags_pos.sql deleted file mode 100644 index ed9b66ae..00000000 --- a/database/update/update_031_tokens_tags_ctags_pos.sql +++ /dev/null @@ -1,11 +0,0 @@ -ALTER TABLE `tokens_tags_optimized` ADD FOREIGN KEY ( `ctag_id` ) REFERENCES `tokens_tags_ctags` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT; - -INSERT INTO `tokens_tags_ctags`(`ctag`) SELECT DISTINCT ctag FROM `tokens_tags_optimized`; -UPDATE `tokens_tags_optimized` tto JOIN `tokens_tags_ctags` ttc USING(ctag) SET tto.ctag_id = ttc.id; - -ALTER TABLE `tokens_tags_optimized` ADD `pos` VARCHAR( 20 ) NOT NULL ; - -UPDATE `tokens_tags_optimized` SET pos = SUBSTRING_INDEX( SUBSTRING_INDEX(ctag, ':', 1 ) , ':', -1 ); - -ALTER TABLE `tokens_tags_optimized` DROP `ctag`; -ALTER TABLE `tokens_tags_optimized` CHANGE `ctag_id` `ctag_id` INT( 11 ) NOT NULL ; diff --git a/database/update/update_033_tokens_tags_reload.sql b/database/update/update_033_tokens_tags_reload.sql deleted file mode 100644 index 58fa55e0..00000000 --- a/database/update/update_033_tokens_tags_reload.sql +++ /dev/null @@ -1,5 +0,0 @@ -CREATE ALGORITHM = UNDEFINED VIEW `tokens_tags` AS -SELECT token_tag_id,token_id,b.text as base,base_id,ctag,disamb -FROM tokens_tags_optimized AS tt -LEFT JOIN bases AS b ON b.id=tt.base_id -LEFT JOIN tokens_tags_ctags ON(tt.ctag_id = tokens_tags_ctags.id); \ No newline at end of file diff --git a/database/update/update_034_ctag_unique.sql b/database/update/update_034_ctag_unique.sql deleted file mode 100644 index 9e65aa10..00000000 --- a/database/update/update_034_ctag_unique.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `tokens_tags_ctags` ADD UNIQUE INDEX `ctag_UNIQUE` (`ctag` ASC) ; \ No newline at end of file diff --git a/database/update/update_035_no_cascade_delete_for_types.sql b/database/update/update_035_no_cascade_delete_for_types.sql deleted file mode 100644 index 38f81d80..00000000 --- a/database/update/update_035_no_cascade_delete_for_types.sql +++ /dev/null @@ -1,20 +0,0 @@ -ALTER TABLE `reports_annotations_optimized` DROP FOREIGN KEY `FK_reports_annotations_annotation_types` , -ADD FOREIGN KEY ( `type_id` ) REFERENCES `gpw`.`annotation_types` ( -`annotation_type_id` -) ON DELETE RESTRICT ON UPDATE CASCADE ; - -ALTER TABLE `relations` DROP FOREIGN KEY `relations_ibfk_5` , -ADD FOREIGN KEY ( `relation_type_id` ) REFERENCES `gpw`.`relation_types` ( -`id` -) ON DELETE RESTRICT ON UPDATE CASCADE ; - -ALTER TABLE `relations` DROP FOREIGN KEY `relations_ibfk_7` , -ADD FOREIGN KEY ( `source_id` ) REFERENCES `gpw`.`reports_annotations_optimized` ( -`id` -) ON DELETE RESTRICT ON UPDATE CASCADE ; - -ALTER TABLE `relations` DROP FOREIGN KEY `relations_ibfk_8` , -ADD FOREIGN KEY ( `target_id` ) REFERENCES `gpw`.`reports_annotations_optimized` ( -`id` -) ON DELETE RESTRICT ON UPDATE CASCADE ; - diff --git a/database/update/update_036_report_content_size.sql b/database/update/update_036_report_content_size.sql deleted file mode 100644 index 462f2098..00000000 --- a/database/update/update_036_report_content_size.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `reports` CHANGE `content` `content` MEDIUMTEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL; diff --git a/database/update/update_037_shared_attributes.sql b/database/update/update_037_shared_attributes.sql deleted file mode 100644 index e9090960..00000000 --- a/database/update/update_037_shared_attributes.sql +++ /dev/null @@ -1,39 +0,0 @@ --- phpMyAdmin SQL Dump --- version 4.0.10deb1 --- http://www.phpmyadmin.net --- --- Host: localhost --- Generation Time: Feb 05, 2015 at 01:55 PM --- Server version: 5.5.41-0ubuntu0.14.04.1 --- PHP Version: 5.5.9-1ubuntu4.5 - -SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; -SET time_zone = "+00:00"; - - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; - --- --- Database: `inforex` --- - --- -------------------------------------------------------- - --- --- Table structure for table `shared_attributes` --- - -CREATE TABLE IF NOT EXISTS `shared_attributes` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(45) CHARACTER SET utf8 DEFAULT NULL, - `type` enum('enum','string') CHARACTER SET utf8 DEFAULT NULL, - `description` varchar(45) CHARACTER SET utf8 DEFAULT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; - -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; diff --git a/database/update/update_038_shared_attributes_enum.sql b/database/update/update_038_shared_attributes_enum.sql deleted file mode 100644 index 0d8f5ac7..00000000 --- a/database/update/update_038_shared_attributes_enum.sql +++ /dev/null @@ -1,48 +0,0 @@ --- phpMyAdmin SQL Dump --- version 4.0.10deb1 --- http://www.phpmyadmin.net --- --- Host: localhost --- Generation Time: Feb 05, 2015 at 01:55 PM --- Server version: 5.5.41-0ubuntu0.14.04.1 --- PHP Version: 5.5.9-1ubuntu4.5 - -SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; -SET time_zone = "+00:00"; - - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; - --- --- Database: `inforex` --- - --- -------------------------------------------------------- - --- --- Table structure for table `shared_attributes_enum` --- - -CREATE TABLE IF NOT EXISTS `shared_attributes_enum` ( - `shared_attribute_id` int(11) NOT NULL AUTO_INCREMENT, - `value` varchar(45) CHARACTER SET utf8 NOT NULL, - `description` varchar(45) CHARACTER SET utf8 NOT NULL, - KEY `shared_attribute_id` (`shared_attribute_id`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; - --- --- Constraints for dumped tables --- - --- --- Constraints for table `shared_attributes_enum` --- -ALTER TABLE `shared_attributes_enum` - ADD CONSTRAINT `shared_attributes_enum_ibfk_1` FOREIGN KEY (`shared_attribute_id`) REFERENCES `shared_attributes` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION; - -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; diff --git a/database/update/update_039_reports_annotations_shared_attributes.sql b/database/update/update_039_reports_annotations_shared_attributes.sql deleted file mode 100644 index 335f765a..00000000 --- a/database/update/update_039_reports_annotations_shared_attributes.sql +++ /dev/null @@ -1,54 +0,0 @@ --- phpMyAdmin SQL Dump --- version 4.0.10deb1 --- http://www.phpmyadmin.net --- --- Host: localhost --- Generation Time: Feb 05, 2015 at 12:56 PM --- Server version: 5.5.41-0ubuntu0.14.04.1 --- PHP Version: 5.5.9-1ubuntu4.5 - -SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; -SET time_zone = "+00:00"; - - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; - --- --- Database: `inforex` --- - --- -------------------------------------------------------- - --- --- Table structure for table `reports_annotations_shared_attributes` --- - -CREATE TABLE IF NOT EXISTS `reports_annotations_shared_attributes` ( - `annotation_id` bigint(20) NOT NULL, - `shared_attribute_id` int(11) NOT NULL, - `value` varchar(45) CHARACTER SET utf8 NOT NULL, - `user_id` int(11) NOT NULL, - UNIQUE KEY `unique_annotations_shared_attributes_values` (`annotation_id`,`shared_attribute_id`), - KEY `annotation_id` (`annotation_id`), - KEY `shared_attribute_id` (`shared_attribute_id`), - KEY `user_id` (`user_id`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; - --- --- Constraints for dumped tables --- - --- --- Constraints for table `reports_annotations_shared_attributes` --- -ALTER TABLE `reports_annotations_shared_attributes` - ADD CONSTRAINT `reports_annotations_shared_attributes_ibfk_1` FOREIGN KEY (`annotation_id`) REFERENCES `reports_annotations_optimized` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION, - ADD CONSTRAINT `reports_annotations_shared_attributes_ibfk_2` FOREIGN KEY (`shared_attribute_id`) REFERENCES `shared_attributes` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION, - ADD CONSTRAINT `reports_annotations_shared_attributes_ibfk_3` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`) ON DELETE CASCADE ON UPDATE NO ACTION; - -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; diff --git a/database/update/update_040_annotation_types_shared_attributes.sql b/database/update/update_040_annotation_types_shared_attributes.sql deleted file mode 100644 index a6dbbdaa..00000000 --- a/database/update/update_040_annotation_types_shared_attributes.sql +++ /dev/null @@ -1,49 +0,0 @@ --- phpMyAdmin SQL Dump --- version 4.0.10deb1 --- http://www.phpmyadmin.net --- --- Host: localhost --- Generation Time: Feb 03, 2015 at 06:22 PM --- Server version: 5.5.41-0ubuntu0.14.04.1 --- PHP Version: 5.5.9-1ubuntu4.5 - -SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; -SET time_zone = "+00:00"; - - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; - --- --- Database: `inforex` --- - --- -------------------------------------------------------- - --- --- Table structure for table `annotation_types_shared_attributes` --- - -CREATE TABLE IF NOT EXISTS `annotation_types_shared_attributes` ( - `annotation_type_id` int(11) NOT NULL, - `shared_attribute_id` int(11) NOT NULL, - KEY `annotation_type_id` (`annotation_type_id`), - KEY `shared_attribute_id` (`shared_attribute_id`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; - --- --- Constraints for dumped tables --- - --- --- Constraints for table `annotation_types_shared_attributes` --- -ALTER TABLE `annotation_types_shared_attributes` - ADD CONSTRAINT `annotation_types_shared_attributes_ibfk_2` FOREIGN KEY (`annotation_type_id`) REFERENCES `annotation_types` (`annotation_type_id`) ON DELETE CASCADE ON UPDATE NO ACTION, - ADD CONSTRAINT `annotation_types_shared_attributes_ibfk_1` FOREIGN KEY (`shared_attribute_id`) REFERENCES `shared_attributes` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION; - -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; diff --git a/database/update/update_041_agreement.sql b/database/update/update_041_agreement.sql deleted file mode 100644 index 354fe5e5..00000000 --- a/database/update/update_041_agreement.sql +++ /dev/null @@ -1,3 +0,0 @@ -UPDATE `corpus_roles` SET `description` = 'Edycja anotacji publicznych' WHERE `corpus_roles`.`role` = 'annotate'; - -INSERT INTO `corpus_roles` (`role`, `description`) VALUES ('', ''), ('annotate_agreement', 'Edycja anotacji prywatnych na potrzeby badania zgodności.'); diff --git a/database/update/update_042_create_corpus.sql b/database/update/update_042_create_corpus.sql deleted file mode 100644 index 3a01f034..00000000 --- a/database/update/update_042_create_corpus.sql +++ /dev/null @@ -1,3 +0,0 @@ -INSERT INTO `roles` (`role`, `description`) VALUES ('create_corpus', 'Prawo do tworzenia nowych korpusów.'); - -ALTER TABLE `corpora` CHANGE `ext` `ext` VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_polish_ci NULL; diff --git a/database/update/update_043_email.sql b/database/update/update_043_email.sql deleted file mode 100644 index 7f44d9fd..00000000 --- a/database/update/update_043_email.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `users` CHANGE `email` `email` VARCHAR(256) CHARACTER SET utf8 COLLATE utf8_polish_ci NOT NULL DEFAULT 'unknown'; diff --git a/database/update/update_044_tasks.sql b/database/update/update_044_tasks.sql deleted file mode 100644 index eb3ebfc8..00000000 --- a/database/update/update_044_tasks.sql +++ /dev/null @@ -1,46 +0,0 @@ --- --- Struktura tabeli dla tabeli `tasks` --- - -CREATE TABLE IF NOT EXISTS `tasks` ( - `task_id` int(11) NOT NULL AUTO_INCREMENT, - `datetime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Data i czas utworzenia zadania.', - `type` varchar(32) COLLATE utf8_polish_ci NOT NULL COMMENT 'Identyfikator zadania.', - `parameters` text COLLATE utf8_polish_ci NOT NULL, - `corpus_id` int(11) NOT NULL, - `user_id` int(11) DEFAULT NULL, - `max_steps` int(11) NOT NULL, - `current_step` int(11) NOT NULL, - `status` enum('new','process','done','error') COLLATE utf8_polish_ci NOT NULL DEFAULT 'new', - PRIMARY KEY (`task_id`), - KEY `corpus_id` (`corpus_id`), - KEY `user_id` (`user_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci AUTO_INCREMENT=44 ; - --- --- Ograniczenia dla zrzutów tabel --- - --- --- Ograniczenia dla tabeli `tasks` --- -ALTER TABLE `tasks` - ADD CONSTRAINT `tasks_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`) ON DELETE SET NULL ON UPDATE CASCADE, - ADD CONSTRAINT `tasks_ibfk_1` FOREIGN KEY (`corpus_id`) REFERENCES `corpora` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; - -CREATE TABLE IF NOT EXISTS `tasks_reports` ( - `task_id` int(11) NOT NULL, - `report_id` bigint(11) NOT NULL, - `status` enum('new','process','done','error') COLLATE utf8_polish_ci NOT NULL, - `message` TEXT, - KEY `document_id` (`report_id`), - KEY `task_id` (`task_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci; - - -ALTER TABLE `tasks_reports` - ADD CONSTRAINT `tasks_reports_ibfk_2` FOREIGN KEY (`report_id`) REFERENCES `reports` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, - ADD CONSTRAINT `tasks_reports_ibfk_1` FOREIGN KEY (`task_id`) REFERENCES `tasks` (`task_id`) ON DELETE CASCADE ON UPDATE CASCADE; - - -INSERT INTO `corpus_roles` (`role`, `description`) VALUES ('tasks', 'Wykonywanie masowych zadań na dokumentach'); diff --git a/database/update/update_045_tasks_update.sql b/database/update/update_045_tasks_update.sql deleted file mode 100644 index 383fa6a9..00000000 --- a/database/update/update_045_tasks_update.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE `tasks` ADD `description` TEXT NULL AFTER `type`; -ALTER TABLE `tasks` ADD `message` TEXT NULL ; diff --git a/database/update/update_046_wccl_rules.sql b/database/update/update_046_wccl_rules.sql deleted file mode 100644 index 1d6dd216..00000000 --- a/database/update/update_046_wccl_rules.sql +++ /dev/null @@ -1,14 +0,0 @@ -CREATE TABLE IF NOT EXISTS `wccl_rules` ( - `wccl_rule_id` int(11) NOT NULL AUTO_INCREMENT, - `user_id` int(11) NOT NULL, - `corpus_id` int(11) NOT NULL, - `rules` text COLLATE utf8_polish_ci, - PRIMARY KEY (`wccl_rule_id`), - UNIQUE KEY `user_id` (`user_id`,`corpus_id`), - KEY `user_id_2` (`user_id`), - KEY `corpus_id` (`corpus_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci AUTO_INCREMENT=1 ; - -ALTER TABLE `wccl_rules` - ADD CONSTRAINT `wccl_rules_ibfk_2` FOREIGN KEY (`corpus_id`) REFERENCES `corpora` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, - ADD CONSTRAINT `wccl_rules_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/database/update/update_047_user_login_max_size.sql b/database/update/update_047_user_login_max_size.sql deleted file mode 100644 index 00706c2d..00000000 --- a/database/update/update_047_user_login_max_size.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `users` CHANGE `login` `login` VARCHAR( 64 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL; \ No newline at end of file diff --git a/database/update/update_048_tasks_datetime_start.sql b/database/update/update_048_tasks_datetime_start.sql deleted file mode 100644 index 77a29972..00000000 --- a/database/update/update_048_tasks_datetime_start.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE `tasks` -ADD COLUMN `datetime_start` TIMESTAMP NULL DEFAULT NULL AFTER `datetime`; diff --git a/database/update/update_048_wccl_match_annotations.sql b/database/update/update_048_wccl_match_annotations.sql deleted file mode 100644 index ec726933..00000000 --- a/database/update/update_048_wccl_match_annotations.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `wccl_rules` ADD `annotations` TEXT NULL ; \ No newline at end of file diff --git a/database/update/update_050_no_cascade.sql b/database/update/update_050_no_cascade.sql deleted file mode 100644 index 80c928eb..00000000 --- a/database/update/update_050_no_cascade.sql +++ /dev/null @@ -1,9 +0,0 @@ -ALTER TABLE `reports` DROP FOREIGN KEY `reports_ibfk_7` , -ADD FOREIGN KEY ( `subcorpus_id` ) REFERENCES `inforex`.`corpus_subcorpora` ( -`subcorpus_id` -) ON DELETE SET NULL ON UPDATE CASCADE ; - -ALTER TABLE `reports` DROP FOREIGN KEY `reports_ibfk_8` , -ADD FOREIGN KEY ( `type` ) REFERENCES `inforex`.`reports_types` ( -`id` -) ON DELETE SET NULL ON UPDATE CASCADE ; diff --git a/database/update/update_051_agreement.sql b/database/update/update_051_agreement.sql deleted file mode 100644 index cb3c0b14..00000000 --- a/database/update/update_051_agreement.sql +++ /dev/null @@ -1,14 +0,0 @@ -UPDATE `corpus_roles` SET description='Edycja anotacji prywatnych' WHERE role='annotate_agreement'; - -ALTER TABLE `reports_annotations_optimized` CHANGE `stage` `stage` ENUM( 'new', 'final', 'discarded', 'agreement' ) CHARACTER SET utf8 COLLATE utf8_polish_ci NOT NULL DEFAULT 'final'; - -ALTER TABLE `corpus_roles` ADD `description_long` TEXT NOT NULL ; - -INSERT INTO `corpus_roles` ( -`role` , -`description` , -`description_long` -) -VALUES ( -'agreement_check', 'Sprawdzanie zgodności anotatorów', 'Dostęp do strony z wynikami zgodności anotatorów. ' -); diff --git a/database/update/update_052_flag_description.sql b/database/update/update_052_flag_description.sql deleted file mode 100644 index 70b3bb26..00000000 --- a/database/update/update_052_flag_description.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `corpora_flags` ADD `description` TEXT NOT NULL ; \ No newline at end of file diff --git a/database/update/update_053_role_delete_annotations.sql b/database/update/update_053_role_delete_annotations.sql deleted file mode 100644 index 6ecb3d9a..00000000 --- a/database/update/update_053_role_delete_annotations.sql +++ /dev/null @@ -1 +0,0 @@ -INSERT INTO `corpus_roles` (`role`, `description`, `description_long`) VALUES ('delete_annotations', 'Prawo do usuwania anotacji', 'Użytkownik może usuwać anotacje (dotyczy anotacji publicznych i prywatnych)'); \ No newline at end of file diff --git a/database/update/update_054_exports.sql b/database/update/update_054_exports.sql deleted file mode 100644 index 085563b8..00000000 --- a/database/update/update_054_exports.sql +++ /dev/null @@ -1,28 +0,0 @@ -CREATE TABLE IF NOT EXISTS `exports` ( - `export_id` bigint(20) NOT NULL AUTO_INCREMENT, - `corpus_id` int(20) NOT NULL, - `datetime_submit` datetime NOT NULL, - `datetime_start` datetime DEFAULT NULL, - `datetime_finish` datetime DEFAULT NULL, - `status` enum('new','process','done','error') COLLATE utf8_polish_ci NOT NULL DEFAULT 'new', - `description` text COLLATE utf8_polish_ci NOT NULL, - `selectors` text COLLATE utf8_polish_ci NOT NULL, - `extractors` text COLLATE utf8_polish_ci NOT NULL, - `indices` text COLLATE utf8_polish_ci NOT NULL, - `message` text COLLATE utf8_polish_ci NOT NULL, - PRIMARY KEY (`export_id`), - KEY `corpus_id` (`corpus_id`), - KEY `status` (`status`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci COMMENT='Tabela z historią zadań eksportu korpusów' AUTO_INCREMENT=1 ; - -ALTER TABLE `exports` - ADD CONSTRAINT `exports_ibfk_1` FOREIGN KEY (`corpus_id`) REFERENCES `corpora` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; - -INSERT INTO `corpus_roles` ( -`role` , -`description` , -`description_long` -) -VALUES ( -'export', 'Eksport korpusu', 'Umożliwia wyeksportowanie określonych dokumentów i danych do postaci plików.' -); \ No newline at end of file diff --git a/database/update/update_055_checkboxes.sql b/database/update/update_055_checkboxes.sql deleted file mode 100644 index fd5b22f1..00000000 --- a/database/update/update_055_checkboxes.sql +++ /dev/null @@ -1,36 +0,0 @@ --- phpMyAdmin SQL Dump --- version 4.0.10deb1 --- http://www.phpmyadmin.net --- --- Host: localhost --- Generation Time: Feb 28, 2017 at 10:15 AM --- Server version: 5.5.54-0ubuntu0.14.04.1 --- PHP Version: 5.5.9-1ubuntu4.21 - -SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; -SET time_zone = "+00:00"; - - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; - --- --- Database: `inforex` --- - --- -------------------------------------------------------- - --- --- Table structure for table `users_checkboxes` --- - -CREATE TABLE IF NOT EXISTS `users_checkboxes` ( - `user_id` int(11) NOT NULL, - `report_id` bigint(20) NOT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1; - -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; \ No newline at end of file diff --git a/database/update/update_055_missing_field.sql b/database/update/update_055_missing_field.sql deleted file mode 100644 index 18438967..00000000 --- a/database/update/update_055_missing_field.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `tasks` ADD `datetime_start` TIMESTAMP NOT NULL AFTER `datetime`; \ No newline at end of file diff --git a/database/update/update_056_report_lang.sql b/database/update/update_056_report_lang.sql deleted file mode 100644 index abf6971a..00000000 --- a/database/update/update_056_report_lang.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE `reports` ADD `lang` VARCHAR( 3 ) NULL , -ADD INDEX ( `lang` ); \ No newline at end of file diff --git a/database/update/update_057_report_user_selection.sql b/database/update/update_057_report_user_selection.sql deleted file mode 100644 index 439288ef..00000000 --- a/database/update/update_057_report_user_selection.sql +++ /dev/null @@ -1 +0,0 @@ -RENAME TABLE `users_checkboxes` TO `reports_users_selection`; \ No newline at end of file diff --git a/database/update/update_058_annotation_types.sql b/database/update/update_058_annotation_types.sql deleted file mode 100644 index f06d2720..00000000 --- a/database/update/update_058_annotation_types.sql +++ /dev/null @@ -1,12 +0,0 @@ -CREATE TABLE IF NOT EXISTS `annotation_types_shortlist` ( - `annotation_type_id` int(11) NOT NULL, - `user_id` int(11) NOT NULL, - `shortlist` int(11) NOT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1; - -ALTER TABLE `annotation_types` -ADD `shortlist` int(11) DEFAULT 0; - -UPDATE `annotation_types` SET `shortlist`= 0 WHERE 1; - -DROP TABLE `annotation_types_common`; diff --git a/database/update/update_059_annotation_access.sql b/database/update/update_059_annotation_access.sql deleted file mode 100644 index 36ac316b..00000000 --- a/database/update/update_059_annotation_access.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE `annotation_sets` ADD `public` INT NOT NULL DEFAULT '1'; -ALTER TABLE `annotation_sets` ADD `user_id` INT( 11 ) NOT NULL DEFAULT '1'; \ No newline at end of file diff --git a/database/update/update_059_users_acitivities.sql b/database/update/update_059_users_acitivities.sql deleted file mode 100644 index 1c81c062..00000000 --- a/database/update/update_059_users_acitivities.sql +++ /dev/null @@ -1,33 +0,0 @@ -CREATE TABLE IF NOT EXISTS `ips` ( - `ip_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `ip` char(39) COLLATE utf8_bin NOT NULL, - PRIMARY KEY (`ip_id`), - UNIQUE KEY `ip` (`ip`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin ; - -CREATE TABLE IF NOT EXISTS `activity_types` ( - `activity_type_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `category` varchar(16) COLLATE utf8_bin NOT NULL, - `name` varchar(32) COLLATE utf8_bin DEFAULT NULL, - KEY `activity_type_id` (`activity_type_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; - -CREATE TABLE IF NOT EXISTS `activities` ( - `activity_page_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, - `datetime` datetime NOT NULL, - `ip_id` int(10) unsigned NOT NULL, - `user_id` int(11) DEFAULT NULL, - `corpus_id` int(11) DEFAULT NULL, - `report_id` int(11) DEFAULT NULL, - `activity_type_id` int(11) NOT NULL, - `execution_time` smallint(5) unsigned DEFAULT NULL, - PRIMARY KEY (`activity_page_id`), - KEY `ip_id` (`ip_id`), - KEY `user_id` (`user_id`), - KEY `corpus_id` (`corpus_id`), - KEY `report_id` (`report_id`), - KEY `activity_type_id` (`activity_type_id`), - KEY `datetime` (`datetime`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; - -CREATE VIEW `activities_view_users` AS select `u`.`screename` AS `screename`,count(0) AS `COUNT(*)`,max(`a`.`datetime`) AS `last_datetime`,`a`.`activity_page_id` AS `activity_page_id`,`a`.`datetime` AS `datetime`,`a`.`ip_id` AS `ip_id`,`a`.`user_id` AS `user_id`,`a`.`corpus_id` AS `corpus_id`,`a`.`report_id` AS `report_id`,`a`.`activity_type_id` AS `activity_type_id`,`a`.`execution_time` AS `execution_time` from (`activities` `a` join `users` `u` on((`a`.`user_id` = `u`.`user_id`))) group by `a`.`user_id`; diff --git a/database/update/update_060_annotation_sets.sql b/database/update/update_060_annotation_sets.sql deleted file mode 100644 index 2ee62cb4..00000000 --- a/database/update/update_060_annotation_sets.sql +++ /dev/null @@ -1,11 +0,0 @@ -ALTER TABLE `annotation_sets` CHANGE `nested` `nested` TINYINT(1) NOT NULL DEFAULT '0'; -ALTER TABLE `annotation_types` CHANGE `cross_sentence` `cross_sentence` TINYINT(1) NOT NULL DEFAULT '0'; - -ALTER TABLE `annotation_sets` CHANGE `description` `name` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL; -ALTER TABLE `annotation_sets` ADD `description` TEXT NOT NULL AFTER `name`; - -ALTER TABLE `annotation_subsets` CHANGE `description` `name` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL; -ALTER TABLE `annotation_subsets` ADD `description` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL AFTER `name`; - -ALTER TABLE `activity_types` CHANGE `name` `name` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL; -ALTER TABLE `annotation_types` CHANGE `level` `level` INT(11) NOT NULL DEFAULT '0'; \ No newline at end of file diff --git a/database/update/update_061_relation_edit.sql b/database/update/update_061_relation_edit.sql deleted file mode 100644 index 9b90c0bb..00000000 --- a/database/update/update_061_relation_edit.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `relations_groups` ADD `annotation_type_id` INT( 11 ) NULL DEFAULT NULL AFTER `annotation_subset_id` ; diff --git a/database/update/update_062_relation_sets.sql b/database/update/update_062_relation_sets.sql deleted file mode 100644 index daac1fc1..00000000 --- a/database/update/update_062_relation_sets.sql +++ /dev/null @@ -1,6 +0,0 @@ -ALTER TABLE `relation_sets` ADD `description` TEXT NOT NULL ; - -CREATE TABLE IF NOT EXISTS `corpora_relations` ( - `corpus_id` int(11) NOT NULL, - `relation_set_id` int(11) NOT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1; \ No newline at end of file diff --git a/database/update/update_063_shared_annotation_sets.sql b/database/update/update_063_shared_annotation_sets.sql deleted file mode 100644 index cbddccad..00000000 --- a/database/update/update_063_shared_annotation_sets.sql +++ /dev/null @@ -1,4 +0,0 @@ -CREATE TABLE IF NOT EXISTS `users_annotation_sets` ( - `user_id` int(11) NOT NULL, - `annotation_set_id` int(11) NOT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1; \ No newline at end of file diff --git a/database/update/update_064_private_relation_sets.sql b/database/update/update_064_private_relation_sets.sql deleted file mode 100644 index 14bd4b05..00000000 --- a/database/update/update_064_private_relation_sets.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE `relation_sets` ADD `public` INT( 1 ) NOT NULL DEFAULT '0', - ADD `user_id` INT( 11 ) NOT NULL DEFAULT '1'; \ No newline at end of file diff --git a/database/update/update_065_annotation_sets_corpora.sql b/database/update/update_065_annotation_sets_corpora.sql deleted file mode 100644 index b5115318..00000000 --- a/database/update/update_065_annotation_sets_corpora.sql +++ /dev/null @@ -1,7 +0,0 @@ -CREATE TABLE IF NOT EXISTS `annotation_sets_corpora` ( - `annotation_set_id` int(11) NOT NULL, - `corpus_id` int(11) NOT NULL, - PRIMARY KEY (`annotation_set_id`,`corpus_id`), - KEY `annotation_set_id` (`annotation_set_id`), - KEY `corpus_id` (`corpus_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci; \ No newline at end of file diff --git a/database/update/update_066_morpho_disamb.sql b/database/update/update_066_morpho_disamb.sql deleted file mode 100644 index aceee914..00000000 --- a/database/update/update_066_morpho_disamb.sql +++ /dev/null @@ -1,53 +0,0 @@ --- create table tagsets - -CREATE TABLE IF NOT EXISTS `tagsets` ( - `tagset_id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(30) NOT NULL, - PRIMARY KEY (`tagset_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci; - - --- add fields to tokens_tags_optimized --- user default NULL - -ALTER TABLE `tokens_tags_optimized` ADD `user_id` INT NULL DEFAULT NULL; - --- adding foreign key constraints -ALTER TABLE `tokens_tags_optimized` -ADD FOREIGN KEY (`user_id`) REFERENCES `users`(`user_id`); - --- adding tagset_id to tags -ALTER TABLE `tokens_tags_ctags` -ADD COLUMN tagset_id INT DEFAULT NULL , -ADD FOREIGN KEY `fk_tagset` ( tagset_id ) REFERENCES tagsets( tagset_id ) ; - --- delete unique on ctag -ALTER TABLE `tokens_tags_ctags` DROP INDEX `ctag_UNIQUE` ; - --- add uniqe on ctag and tagset -ALTER TABLE `tokens_tags_ctags` ADD CONSTRAINT `ctag_tagset_UNIQUE` UNIQUE ( -`ctag` , -`tagset_id` -); - --- adding new role into corpus_roles -INSERT INTO `corpus_roles` ( -`role` , -`description` , -`description_long` -) -VALUES ( -'agreement_morpho', 'Sprawdzanie zgodności dezambiguacji morfologicznych i wybór ostatecznej wersji.', 'Użytkownik widzi decyzje anotatorów i wybiera ostateczną wersję.' -); - --- inserting NKJP tagset into `tagsets` -INSERT INTO `tagsets` (`name`) VALUES ("nkjp"); - --- setting tagset_id of all tokens_tags_ctags to that of "nkjp" -UPDATE `tokens_tags_ctags` dest, -( -SELECT * -FROM `tagsets` -WHERE `name` LIKE "nkjp" -)src -SET dest.`tagset_id` = src.`tagset_id`; \ No newline at end of file diff --git a/database/update/update_066_relations.sql b/database/update/update_066_relations.sql deleted file mode 100644 index 611b41b3..00000000 --- a/database/update/update_066_relations.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `relations` ADD `stage` ENUM( 'final', 'discarded', 'agreement' ) NOT NULL DEFAULT 'final'; \ No newline at end of file diff --git a/database/update/update_067_federation_login_clarin.sql b/database/update/update_067_federation_login_clarin.sql deleted file mode 100644 index 3616fd50..00000000 --- a/database/update/update_067_federation_login_clarin.sql +++ /dev/null @@ -1,3 +0,0 @@ --- alter table - -ALTER TABLE `users` ADD `clarin_login` VARCHAR( 256 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL ; diff --git a/database/update/update_068_morphodisamb_agreement.sql b/database/update/update_068_morphodisamb_agreement.sql deleted file mode 100644 index 2d3500c8..00000000 --- a/database/update/update_068_morphodisamb_agreement.sql +++ /dev/null @@ -1,6 +0,0 @@ --- add stage field to tokens_tags_optimized - -ALTER TABLE `tokens_tags_optimized` -ADD `stage` ENUM( 'tagger', 'agreement', 'final' ) -CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'tagger' -COMMENT 'Describes stage of chosen tag, tagger- generated by tagger, agreement- set by user, final- set by final user with agreement check'; \ No newline at end of file diff --git a/database/update/update_069_adding_report_prespectives_for_morpho.sql b/database/update/update_069_adding_report_prespectives_for_morpho.sql deleted file mode 100644 index d431a3a3..00000000 --- a/database/update/update_069_adding_report_prespectives_for_morpho.sql +++ /dev/null @@ -1,5 +0,0 @@ --- inserting pages morphodisamb and morphodisambagreement - -INSERT INTO `report_perspectives` (`id`, `title`, `description`, `order`) VALUES -("morphodisamb","Morphological Disambiguation","Show and edit user morphological disamgibuations",300), -("morphodisambagreement","Morphological Disambiguation Agreement","Show and edit final morphological disambiguations",310); \ No newline at end of file diff --git a/database/update/update_070_relation_agreement.sql b/database/update/update_070_relation_agreement.sql deleted file mode 100644 index e36ed911..00000000 --- a/database/update/update_070_relation_agreement.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE `relations` ADD INDEX ( `stage` ) ; -INSERT INTO `report_perspectives` (`id`, `title`, `description`, `order`) VALUES ('relation_agreement', 'Relation agreement', '', '11'); \ No newline at end of file diff --git a/database/update/update_071_annotation_agreement.sql b/database/update/update_071_annotation_agreement.sql deleted file mode 100644 index 3985adb6..00000000 --- a/database/update/update_071_annotation_agreement.sql +++ /dev/null @@ -1 +0,0 @@ -UPDATE `report_perspectives` SET `title` = 'Annotation agreement' WHERE `report_perspectives`.`id` = 'agreement'; \ No newline at end of file diff --git a/database/update/update_071_default_nulls.sql b/database/update/update_071_default_nulls.sql deleted file mode 100644 index 436ab4c5..00000000 --- a/database/update/update_071_default_nulls.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `exports` CHANGE `description` `description` TEXT CHARACTER SET utf8 COLLATE utf8_polish_ci NULL, CHANGE `selectors` `selectors` TEXT CHARACTER SET utf8 COLLATE utf8_polish_ci NULL, CHANGE `extractors` `extractors` TEXT CHARACTER SET utf8 COLLATE utf8_polish_ci NULL, CHANGE `indices` `indices` TEXT CHARACTER SET utf8 COLLATE utf8_polish_ci NULL, CHANGE `message` `message` TEXT CHARACTER SET utf8 COLLATE utf8_polish_ci NULL; \ No newline at end of file diff --git a/database/update/update_072_tonekization_null.sql b/database/update/update_072_tonekization_null.sql deleted file mode 100644 index ca687160..00000000 --- a/database/update/update_072_tonekization_null.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `reports` CHANGE `tokenization` `tokenization` VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_polish_ci NULL DEFAULT NULL; \ No newline at end of file diff --git a/database/update/update_073_reports_nulls.sql b/database/update/update_073_reports_nulls.sql deleted file mode 100644 index 67cfb663..00000000 --- a/database/update/update_073_reports_nulls.sql +++ /dev/null @@ -1,5 +0,0 @@ -ALTER TABLE `reports` CHANGE `date` `date` DATE NULL DEFAULT NULL , -CHANGE `title` `title` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL , -CHANGE `source` `source` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL , -CHANGE `author` `author` VARCHAR( 128 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL , -CHANGE `content` `content` MEDIUMTEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL \ No newline at end of file diff --git a/database/update/update_074_exports.sql b/database/update/update_074_exports.sql deleted file mode 100644 index d30cf5b0..00000000 --- a/database/update/update_074_exports.sql +++ /dev/null @@ -1,19 +0,0 @@ -ALTER TABLE `exports` ADD `progress` INT NOT NULL DEFAULT '0'; -ALTER TABLE `exports` ADD `statistics` TEXT NULL DEFAULT NULL AFTER `progress`; - -CREATE TABLE `export_errors` ( - `id` int(11) NOT NULL, - `export_id` int(11) NOT NULL, - `message` text NOT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1; - -ALTER TABLE `export_errors` - ADD PRIMARY KEY (`id`); - -ALTER TABLE `export_errors` - MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; - -ALTER TABLE `export_errors` ADD `error_details` TEXT NOT NULL AFTER `message`; -ALTER TABLE `export_errors` ADD `count` INT NOT NULL AFTER `error_details`; -ALTER TABLE `export_errors` CHANGE `message` `message` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL; -ALTER TABLE `export_errors` CHANGE `error_details` `error_details` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL; \ No newline at end of file diff --git a/database/update/update_075_add_tagger_field_to_exports.sql b/database/update/update_075_add_tagger_field_to_exports.sql deleted file mode 100644 index 9671a0ed..00000000 --- a/database/update/update_075_add_tagger_field_to_exports.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `exports` ADD `tagging` VARCHAR( 16 ) DEFAULT "tagger" NOT NULL AFTER `indices`; \ No newline at end of file diff --git a/database/update/update_075_corpora_date.sql b/database/update/update_075_corpora_date.sql deleted file mode 100644 index 2cc4305b..00000000 --- a/database/update/update_075_corpora_date.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `corpora` ADD `date_created` DATETIME NULL DEFAULT NULL AFTER `ext`; \ No newline at end of file diff --git a/database/update/update_075_upload.sql b/database/update/update_075_upload.sql deleted file mode 100644 index a03ecd8e..00000000 --- a/database/update/update_075_upload.sql +++ /dev/null @@ -1,8 +0,0 @@ -ALTER TABLE `reports` ADD `filename` TEXT NULL AFTER `lang`; -ALTER TABLE `reports` CHANGE `tokenization` `tokenization` VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_polish_ci NULL; - -ALTER TABLE `reports` CHANGE `date` `date` DATE NULL, -CHANGE `title` `title` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL, -CHANGE `source` `source` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL, -CHANGE `author` `author` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL, -CHANGE `content` `content` MEDIUMTEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL; \ No newline at end of file diff --git a/database/update/update_076_flags.sql b/database/update/update_076_flags.sql deleted file mode 100644 index 99617908..00000000 --- a/database/update/update_076_flags.sql +++ /dev/null @@ -1,59 +0,0 @@ --- Flag status history table. -CREATE TABLE `flag_status_history` ( - `report_id` bigint(20) NOT NULL, - `flag_id` int(11) NOT NULL, - `user_id` int(11) NOT NULL, - `new_status` int(11) NOT NULL, - `old_status` int(11) NOT NULL, - `date` DATETIME NOT NULL -) ENGINE=InnoDB; - -ALTER TABLE `flag_status_history` - ADD KEY `report_id` (`report_id`), - ADD KEY `flag_id` (`flag_id`), - ADD KEY `user_id` (`user_id`), - ADD KEY `new_status` (`new_status`), - ADD KEY `old_status` (`old_status`); - -ALTER TABLE `flag_status_history` - ADD CONSTRAINT `flag_status_history_ibfk_1` FOREIGN KEY (`report_id`) REFERENCES `reports` (`id`), - ADD CONSTRAINT `flag_status_history_ibfk_2` FOREIGN KEY (`flag_id`) REFERENCES `corpora_flags` (`corpora_flag_id`), - ADD CONSTRAINT `flag_status_history_ibfk_3` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`), - ADD CONSTRAINT `flag_status_history_ibfk_4` FOREIGN KEY (`new_status`) REFERENCES `flags` (`flag_id`), - ADD CONSTRAINT `flag_status_history_ibfk_5` FOREIGN KEY (`old_status`) REFERENCES `flags` (`flag_id`); - -ALTER TABLE `flag_status_history` ADD `id` BIGINT(22) NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY (`id`); - --- Stored procedure -DROP procedure IF EXISTS `changeFlagStatus`; - -DELIMITER $$ -CREATE PROCEDURE `changeFlagStatus`( - IN flag_id INT(11), - IN flag_status INT(11), - IN report_id INT(11), - IN user_id INT(11)) - BEGIN - -- Previous flag status. - DECLARE old_status INT(11); - - -- Store the previous flag status into old_status variable. - SELECT rf.flag_id INTO old_status FROM reports_flags rf - WHERE (rf.report_id = report_id AND rf.corpora_flag_id = flag_id); - - -- Update the document's flag status. - REPLACE INTO reports_flags(corpora_flag_id, report_id, flag_id) - VALUES(flag_id, report_id, flag_status); - - -- Store the change in the flag status history table. - INSERT INTO flag_status_history (date, report_id, flag_id, user_id, new_status, old_status) - VALUES (CURRENT_TIMESTAMP, report_id, flag_id, user_id, flag_status, IFNULL(old_status,-1)); - END$$ - -DELIMITER ; - --- Adding perspective -INSERT INTO `report_perspectives` (`id`, `title`, `description`, `order`) VALUES ('flag_history', 'Flag history', 'Show the history of flag changes.', '320'); - --- Adding corpus role -INSERT INTO `corpus_roles` (`role`, `description`, `description_long`) VALUES ('flag_history', 'Sprawdzanie historii flag', ''); diff --git a/database/update/update_076_roles.sql b/database/update/update_076_roles.sql deleted file mode 100644 index 5178f202..00000000 --- a/database/update/update_076_roles.sql +++ /dev/null @@ -1,24 +0,0 @@ -/* -Changing the length of the role column in roles and users_roles tables. - */ -LOCK TABLES -roles WRITE, -users_roles WRITE; - -ALTER TABLE users_roles -DROP FOREIGN KEY users_roles_ibfk_2; - -ALTER TABLE users_roles MODIFY role varchar(32); - -ALTER TABLE roles MODIFY role varchar(32); -ALTER TABLE users_roles -ADD CONSTRAINT users_roles_ibfk_2 FOREIGN KEY (role) -REFERENCES roles (role); - -UNLOCK TABLES; - -/* -Adding new roles - */ -INSERT INTO `roles` (`role`, `description`) VALUES ('editor_schema_events', 'Edit schema events.'); -INSERT INTO `roles` (`role`, `description`) VALUES ('editor_schema_relations', 'Edit schema relations.'); \ No newline at end of file diff --git a/database/update/update_077_tagsets.sql b/database/update/update_077_tagsets.sql deleted file mode 100644 index 3696b7b1..00000000 --- a/database/update/update_077_tagsets.sql +++ /dev/null @@ -1,2 +0,0 @@ -INSERT INTO `tagsets` (`tagset_id`, `name`) VALUES ('2', 'English'), ('3', 'German'); -ALTER TABLE `reports` CHANGE `tokenization` `tokenization` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_polish_ci NULL DEFAULT NULL; \ No newline at end of file diff --git a/database/update/update_078_annotation_types_attributes.sql b/database/update/update_078_annotation_types_attributes.sql deleted file mode 100644 index e4c747c8..00000000 --- a/database/update/update_078_annotation_types_attributes.sql +++ /dev/null @@ -1,32 +0,0 @@ -START TRANSACTION; - -DROP TABLE IF EXISTS `annotation_types_attributes_temp`; - -CREATE TABLE `annotation_types_attributes_temp` ( `id` INT(11) NOT NULL , `annotation_type_id` INT(11) NOT NULL , `name` VARCHAR(32) NOT NULL , `type` ENUM('radio', 'string') NOT NULL ) ENGINE = InnoDB; - -INSERT INTO annotation_types_attributes_temp (id, annotation_type_id, name, type) - SELECT ata.id, at.annotation_type_id, ata.name, ata.type FROM `annotation_types_attributes` ata - JOIN annotation_types at ON at.name = ata.annotation_type; - -SET FOREIGN_KEY_CHECKS = 0; - -DROP TABLE IF EXISTS `annotation_types_attributes`; - -SET FOREIGN_KEY_CHECKS = 1; - -CREATE TABLE `annotation_types_attributes` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `annotation_type_id` INT(11) NOT NULL, - `name` varchar(32) CHARACTER SET utf8 NOT NULL, - `type` enum('radio','string') CHARACTER SET utf8 NOT NULL, - PRIMARY KEY (`id`), - KEY `annotation_type_id` (`annotation_type_id`), - CONSTRAINT `annotation_types_attributes_ibfk_1` FOREIGN KEY (`annotation_type_id`) REFERENCES `annotation_types` (`annotation_type_id`) ON DELETE CASCADE ON UPDATE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=147 DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci; - -INSERT INTO annotation_types_attributes (id, annotation_type_id, name, type) - SELECT * FROM `annotation_types_attributes_temp`; - -DROP TABLE `annotation_types_attributes_temp`; - -COMMIT; \ No newline at end of file diff --git a/database/update/update_078_message_null.sql b/database/update/update_078_message_null.sql deleted file mode 100644 index 2632d78d..00000000 --- a/database/update/update_078_message_null.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `tasks_reports` CHANGE `message` `message` TEXT CHARACTER SET utf8 COLLATE utf8_polish_ci NULL; \ No newline at end of file diff --git a/database/update/update_079_import_annotations.sql b/database/update/update_079_import_annotations.sql deleted file mode 100644 index d1c67818..00000000 --- a/database/update/update_079_import_annotations.sql +++ /dev/null @@ -1 +0,0 @@ -INSERT INTO `report_perspectives` (`id`, `title`, `description`, `order`) VALUES ('importannotations', 'Import annotations', 'Import annotations from a .CCL file.', '150'); diff --git a/database/update/update_080_report_translations.sql b/database/update/update_080_report_translations.sql deleted file mode 100644 index 818ba2f9..00000000 --- a/database/update/update_080_report_translations.sql +++ /dev/null @@ -1,4 +0,0 @@ -ALTER TABLE `reports` ADD `parent_report_id` BIGINT(20) NULL DEFAULT NULL AFTER `filename`; -ALTER TABLE reports ADD CONSTRAINT fk_parent_report_id FOREIGN KEY (parent_report_id) REFERENCES reports(id); -INSERT INTO `report_perspectives` (`id`, `title`, `description`, `order`) VALUES ('edittranslation', 'Edit translation', 'Edit document translation', '320'); -INSERT INTO `report_perspectives` (`id`, `title`, `description`, `order`) VALUES ('extendedmetadata', 'Extended metadata', 'Metadata including translations, images and document content.', '325'); \ No newline at end of file diff --git a/database/update/update_081_import_languages.sql b/database/update/update_081_import_languages.sql deleted file mode 100644 index f9727b96..00000000 --- a/database/update/update_081_import_languages.sql +++ /dev/null @@ -1,21 +0,0 @@ -CREATE TABLE `lang` ( - `code` varchar(3), - `language` varchar(255) NOT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1; - -ALTER TABLE `lang` ADD PRIMARY KEY(`code`); - -INSERT INTO lang (code, language) VALUES ("aar", "Afar"),("abk", "Abkhazian"),("ace", "Achinese"),("ach", "Acoli"),("ada", "Adangme"),("ady", "Adyghe; Adygei"),("afa", "Afro-Asiatic languages"),("afh", "Afrihili"),("afr", "Afrikaans"),("ain", "Ainu"),("aka", "Akan"),("akk", "Akkadian"),("alb", "Albanian"),("ale", "Aleut"),("alg", "Algonquian languages"),("alt", "Southern Altai"),("amh", "Amharic"),("ang", "English, Old (ca.450-1100)"),("anp", "Angika"),("apa", "Apache languages"),("ara", "Arabic"),("arc", "Official Aramaic (700-300 BCE); Imperial Aramaic (700-300 BCE)"),("arg", "Aragonese"),("arm", "Armenian"),("arn", "Mapudungun; Mapuche"),("arp", "Arapaho"),("art", "Artificial languages"),("arw", "Arawak"),("asm", "Assamese"),("ast", "Asturian; Bable; Leonese; Asturleonese"),("ath", "Athapascan languages"),("aus", "Australian languages"),("ava", "Avaric"),("ave", "Avestan"),("awa", "Awadhi"),("aym", "Aymara"),("aze", "Azerbaijani"),("bad", "Banda languages"),("bai", "Bamileke languages"),("bak", "Bashkir"),("bal", "Baluchi"),("bam", "Bambara"),("ban", "Balinese"),("baq", "Basque"),("bas", "Basa"),("bat", "Baltic languages"),("bej", "Beja; Bedawiyet"),("bel", "Belarusian"),("bem", "Bemba"),("ben", "Bengali"),("ber", "Berber languages"),("bho", "Bhojpuri"),("bih", "Bihari languages"),("bik", "Bikol"),("bin", "Bini; Edo"),("bis", "Bislama"),("bla", "Siksika"),("bnt", "Bantu (Other)"),("bos", "Bosnian"),("bra", "Braj"),("bre", "Breton"),("btk", "Batak languages"),("bua", "Buriat"),("bug", "Buginese"),("bul", "Bulgarian"),("bur", "Burmese"),("byn", "Blin; Bilin"),("cad", "Caddo"),("cai", "Central American Indian languages"),("car", "Galibi Carib"),("cat", "Catalan; Valencian"),("cau", "Caucasian languages"),("ceb", "Cebuano"),("cel", "Celtic languages"),("cha", "Chamorro"),("chb", "Chibcha"),("che", "Chechen"),("chg", "Chagatai"),("chi", "Chinese"),("chk", "Chuukese"),("chm", "Mari"),("chn", "Chinook jargon"),("cho", "Choctaw"),("chp", "Chipewyan; Dene Suline"),("chr", "Cherokee"),("chu", "Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic"),("chv", "Chuvash"),("chy", "Cheyenne"),("cmc", "Chamic languages"),("cop", "Coptic"),("cor", "Cornish"),("cos", "Corsican"),("cpe", "Creoles and pidgins, English based"),("cpf", "Creoles and pidgins, French-based "),("cpp", "Creoles and pidgins, Portuguese-based "),("cre", "Cree"),("crh", "Crimean Tatar; Crimean Turkish"),("crp", "Creoles and pidgins "),("csb", "Kashubian"),("cus", "Cushitic languages"),("cze", "Czech"),("dak", "Dakota"),("dan", "Danish"),("dar", "Dargwa"),("day", "Land Dayak languages"),("del", "Delaware"),("den", "Slave (Athapascan)"),("dgr", "Dogrib"),("din", "Dinka"),("div", "Divehi; Dhivehi; Maldivian"),("doi", "Dogri"),("dra", "Dravidian languages"),("dsb", "Lower Sorbian"),("dua", "Duala"),("dum", "Dutch, Middle (ca.1050-1350)"),("dut", "Dutch; Flemish"),("dyu", "Dyula"),("dzo", "Dzongkha"),("efi", "Efik"),("egy", "Egyptian (Ancient)"),("eka", "Ekajuk"),("elx", "Elamite"),("eng", "English"),("enm", "English, Middle (1100-1500)"),("epo", "Esperanto"),("est", "Estonian"),("ewe", "Ewe"),("ewo", "Ewondo"),("fan", "Fang"),("fao", "Faroese"),("fat", "Fanti"),("fij", "Fijian"),("fil", "Filipino; Pilipino"),("fin", "Finnish"),("fiu", "Finno-Ugrian languages"),("fon", "Fon"),("fre", "French"),("frm", "French, Middle (ca.1400-1600)"),("fro", "French, Old (842-ca.1400)"),("frr", "Northern Frisian"),("frs", "Eastern Frisian"),("fry", "Western Frisian"),("ful", "Fulah"),("fur", "Friulian"),("gaa", "Ga"),("gay", "Gayo"),("gba", "Gbaya"),("gem", "Germanic languages"),("geo", "Georgian"),("ger", "German"),("gez", "Geez"),("gil", "Gilbertese"),("gla", "Gaelic; Scottish Gaelic"),("gle", "Irish"),("glg", "Galician"),("glv", "Manx"),("gmh", "German, Middle High (ca.1050-1500)"),("goh", "German, Old High (ca.750-1050)"),("gon", "Gondi"),("gor", "Gorontalo"),("got", "Gothic"),("grb", "Grebo"),("grc", "Greek, Ancient (to 1453)"),("gre", "Greek, Modern (1453-)"),("grn", "Guarani"),("gsw", "Swiss German; Alemannic; Alsatian"),("guj", "Gujarati"),("gwi", "Gwich'in"),("hai", "Haida"),("hat", "Haitian; Haitian Creole"),("hau", "Hausa"),("haw", "Hawaiian"),("heb", "Hebrew"),("her", "Herero"),("hil", "Hiligaynon"),("him", "Himachali languages; Western Pahari languages"),("hin", "Hindi"),("hit", "Hittite"),("hmn", "Hmong; Mong"),("hmo", "Hiri Motu"),("hrv", "Croatian"),("hsb", "Upper Sorbian"),("hun", "Hungarian"),("hup", "Hupa"),("iba", "Iban"),("ibo", "Igbo"),("ice", "Icelandic"),("ido", "Ido"),("iii", "Sichuan Yi; Nuosu"),("ijo", "Ijo languages"),("iku", "Inuktitut"),("ile", "Interlingue; Occidental"),("ilo", "Iloko"),("ina", "Interlingua (International Auxiliary Language Association)"),("inc", "Indic languages"),("ind", "Indonesian"),("ine", "Indo-European languages"),("inh", "Ingush"),("ipk", "Inupiaq"),("ira", "Iranian languages"),("iro", "Iroquoian languages"),("ita", "Italian"),("jav", "Javanese"),("jbo", "Lojban"),("jpn", "Japanese"),("jpr", "Judeo-Persian"),("jrb", "Judeo-Arabic"),("kaa", "Kara-Kalpak"),("kab", "Kabyle"),("kac", "Kachin; Jingpho"),("kal", "Kalaallisut; Greenlandic"),("kam", "Kamba"),("kan", "Kannada"),("kar", "Karen languages"),("kas", "Kashmiri"),("kau", "Kanuri"),("kaw", "Kawi"),("kaz", "Kazakh"),("kbd", "Kabardian"),("kha", "Khasi"),("khi", "Khoisan languages"),("khm", "Central Khmer"),("kho", "Khotanese; Sakan"),("kik", "Kikuyu; Gikuyu"),("kin", "Kinyarwanda"),("kir", "Kirghiz; Kyrgyz"),("kmb", "Kimbundu"),("kok", "Konkani"),("kom", "Komi"),("kon", "Kongo"),("kor", "Korean"),("kos", "Kosraean"),("kpe", "Kpelle"),("krc", "Karachay-Balkar"),("krl", "Karelian"),("kro", "Kru languages"),("kru", "Kurukh"),("kua", "Kuanyama; Kwanyama"),("kum", "Kumyk"),("kur", "Kurdish"),("kut", "Kutenai"),("lad", "Ladino"),("lah", "Lahnda"),("lam", "Lamba"),("lao", "Lao"),("lat", "Latin"),("lav", "Latvian"),("lez", "Lezghian"),("lim", "Limburgan; Limburger; Limburgish"),("lin", "Lingala"),("lit", "Lithuanian"),("lol", "Mongo"),("loz", "Lozi"),("ltz", "Luxembourgish; Letzeburgesch"),("lua", "Luba-Lulua"),("lub", "Luba-Katanga"),("lug", "Ganda"),("lui", "Luiseno"),("lun", "Lunda"),("luo", "Luo (Kenya and Tanzania)"),("lus", "Lushai"),("mac", "Macedonian"),("mad", "Madurese"),("mag", "Magahi"),("mah", "Marshallese"),("mai", "Maithili"),("mak", "Makasar"),("mal", "Malayalam"),("man", "Mandingo"),("mao", "Maori"),("map", "Austronesian languages"),("mar", "Marathi"),("mas", "Masai"),("may", "Malay"),("mdf", "Moksha"),("mdr", "Mandar"),("men", "Mende"),("mga", "Irish, Middle (900-1200)"),("mic", "Mi'kmaq; Micmac"),("min", "Minangkabau"),("mis", "Uncoded languages"),("mkh", "Mon-Khmer languages"),("mlg", "Malagasy"),("mlt", "Maltese"),("mnc", "Manchu"),("mni", "Manipuri"),("mno", "Manobo languages"),("moh", "Mohawk"),("mon", "Mongolian"),("mos", "Mossi"),("mul", "Multiple languages"),("mun", "Munda languages"),("mus", "Creek"),("mwl", "Mirandese"),("mwr", "Marwari"),("myn", "Mayan languages"),("myv", "Erzya"),("nah", "Nahuatl languages"),("nai", "North American Indian languages"),("nap", "Neapolitan"),("nau", "Nauru"),("nav", "Navajo; Navaho"),("nbl", "Ndebele, South; South Ndebele"),("nde", "Ndebele, North; North Ndebele"),("ndo", "Ndonga"),("nds", "Low German; Low Saxon; German, Low; Saxon, Low"),("nep", "Nepali"),("new", "Nepal Bhasa; Newari"),("nia", "Nias"),("nic", "Niger-Kordofanian languages"),("niu", "Niuean"),("nno", "Norwegian Nynorsk; Nynorsk, Norwegian"),("nob", "Bokmål, Norwegian; Norwegian Bokmål"),("nog", "Nogai"),("non", "Norse, Old"),("nor", "Norwegian"),("nqo", "N'Ko"),("nso", "Pedi; Sepedi; Northern Sotho"),("nub", "Nubian languages"),("nwc", "Classical Newari; Old Newari; Classical Nepal Bhasa"),("nya", "Chichewa; Chewa; Nyanja"),("nym", "Nyamwezi"),("nyn", "Nyankole"),("nyo", "Nyoro"),("nzi", "Nzima"),("oci", "Occitan (post 1500); Provençal"),("oji", "Ojibwa"),("ori", "Oriya"),("orm", "Oromo"),("osa", "Osage"),("oss", "Ossetian; Ossetic"),("ota", "Turkish, Ottoman (1500-1928)"),("oto", "Otomian languages"),("paa", "Papuan languages"),("pag", "Pangasinan"),("pal", "Pahlavi"),("pam", "Pampanga; Kapampangan"),("pan", "Panjabi; Punjabi"),("pap", "Papiamento"),("pau", "Palauan"),("peo", "Persian, Old (ca.600-400 B.C.)"),("per", "Persian"),("phi", "Philippine languages"),("phn", "Phoenician"),("pli", "Pali"),("pol", "Polish"),("pon", "Pohnpeian"),("por", "Portuguese"),("pra", "Prakrit languages"),("pro", "Provençal, Old (to 1500)"),("pus", "Pushto; Pashto"),("que", "Quechua"),("raj", "Rajasthani"),("rap", "Rapanui"),("rar", "Rarotongan; Cook Islands Maori"),("roa", "Romance languages"),("roh", "Romansh"),("rom", "Romany"),("rum", "Romanian; Moldavian; Moldovan"),("run", "Rundi"),("rup", "Aromanian; Arumanian; Macedo-Romanian"),("rus", "Russian"),("sad", "Sandawe"),("sag", "Sango"),("sah", "Yakut"),("sai", "South American Indian (Other)"),("sal", "Salishan languages"),("sam", "Samaritan Aramaic"),("san", "Sanskrit"),("sas", "Sasak"),("sat", "Santali"),("scn", "Sicilian"),("sco", "Scots"),("sel", "Selkup"),("sem", "Semitic languages"),("sga", "Irish, Old (to 900)"),("sgn", "Sign Languages"),("shn", "Shan"),("sid", "Sidamo"),("sin", "Sinhala; Sinhalese"),("sio", "Siouan languages"),("sit", "Sino-Tibetan languages"),("sla", "Slavic languages"),("slo", "Slovak"),("slv", "Slovenian"),("sma", "Southern Sami"),("sme", "Northern Sami"),("smi", "Sami languages"),("smj", "Lule Sami"),("smn", "Inari Sami"),("smo", "Samoan"),("sms", "Skolt Sami"),("sna", "Shona"),("snd", "Sindhi"),("snk", "Soninke"),("sog", "Sogdian"),("som", "Somali"),("son", "Songhai languages"),("sot", "Sotho, Southern"),("spa", "Spanish; Castilian"),("srd", "Sardinian"),("srn", "Sranan Tongo"),("srp", "Serbian"),("srr", "Serer"),("ssa", "Nilo-Saharan languages"),("ssw", "Swati"),("suk", "Sukuma"),("sun", "Sundanese"),("sus", "Susu"),("sux", "Sumerian"),("swa", "Swahili"),("swe", "Swedish"),("syc", "Classical Syriac"),("syr", "Syriac"),("tah", "Tahitian"),("tai", "Tai languages"),("tam", "Tamil"),("tat", "Tatar"),("tel", "Telugu"),("tem", "Timne"),("ter", "Tereno"),("tet", "Tetum"),("tgk", "Tajik"),("tgl", "Tagalog"),("tha", "Thai"),("tib", "Tibetan"),("tig", "Tigre"),("tir", "Tigrinya"),("tiv", "Tiv"),("tkl", "Tokelau"),("tlh", "Klingon; tlhIngan-Hol"),("tli", "Tlingit"),("tmh", "Tamashek"),("tog", "Tonga (Nyasa)"),("ton", "Tonga (Tonga Islands)"),("tpi", "Tok Pisin"),("tsi", "Tsimshian"),("tsn", "Tswana"),("tso", "Tsonga"),("tuk", "Turkmen"),("tum", "Tumbuka"),("tup", "Tupi languages"),("tur", "Turkish"),("tut", "Altaic languages"),("tvl", "Tuvalu"),("twi", "Twi"),("tyv", "Tuvinian"),("udm", "Udmurt"),("uga", "Ugaritic"),("uig", "Uighur; Uyghur"),("ukr", "Ukrainian"),("umb", "Umbundu"),("und", "Undetermined"),("urd", "Urdu"),("uzb", "Uzbek"),("vai", "Vai"),("ven", "Venda"),("vie", "Vietnamese"),("vol", "Volapük"),("vot", "Votic"),("wak", "Wakashan languages"),("wal", "Walamo"),("war", "Waray"),("was", "Washo"),("wel", "Welsh"),("wen", "Sorbian languages"),("wln", "Walloon"),("wol", "Wolof"),("xal", "Kalmyk; Oirat"),("xho", "Xhosa"),("yao", "Yao"),("yap", "Yapese"),("yid", "Yiddish"),("yor", "Yoruba"),("ypk", "Yupik languages"),("zap", "Zapotec"),("zbl", "Blissymbols; Blissymbolics; Bliss"),("zen", "Zenaga"),("zha", "Zhuang; Chuang"),("znd", "Zande languages"),("zul", "Zulu"),("zun", "Zuni"),("zxx", "No linguistic content; Not applicable"),("zza", "Zaza; Dimili; Dimli; Kirdki; Kirmanjki; Zazaki"); - -ALTER TABLE reports MODIFY lang VARCHAR(3); - -CREATE INDEX reports_lang_index ON reports (lang); - -UPDATE reports SET lang = CASE WHEN lang = 'cz' THEN 'cze' WHEN lang = 'hr' THEN 'hun' WHEN lang = 'pl' THEN 'pol' WHEN lang = 'ru' THEN 'rus' WHEN lang = 'sk' THEN 'slo' WHEN lang = 'sl' THEN 'slv' WHEN lang = 'uk' THEN 'ukr' ELSE NULL END; - -ALTER TABLE reports MODIFY lang CHAR(3); -ALTER TABLE `reports` CHANGE `lang` `lang` CHAR(3) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL; - -ALTER TABLE `lang` CHANGE `code` `code` CHAR(3) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL; - -ALTER TABLE reports ADD FOREIGN KEY (lang) REFERENCES lang(code); diff --git a/database/update/update_082_cascade_flag_history.sql b/database/update/update_082_cascade_flag_history.sql deleted file mode 100644 index 1989ad89..00000000 --- a/database/update/update_082_cascade_flag_history.sql +++ /dev/null @@ -1,4 +0,0 @@ -ALTER TABLE `flag_status_history` DROP FOREIGN KEY `flag_status_history_ibfk_1` , -ADD FOREIGN KEY ( `report_id` ) REFERENCES `reports` ( -`id` -) ON DELETE CASCADE ON UPDATE RESTRICT ; \ No newline at end of file diff --git a/database/update/update_083_reports_uesrs_selection_indices.sql b/database/update/update_083_reports_uesrs_selection_indices.sql deleted file mode 100644 index 6005de4b..00000000 --- a/database/update/update_083_reports_uesrs_selection_indices.sql +++ /dev/null @@ -1,9 +0,0 @@ -ALTER TABLE `reports_users_selection` ADD INDEX(`user_id`); - -ALTER TABLE `reports_users_selection` ADD FOREIGN KEY (`user_id`) REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE; - -ALTER TABLE `reports_users_selection` ADD INDEX(`report_id`); - -ALTER TABLE `reports_users_selection` ADD FOREIGN KEY (`report_id`) REFERENCES `reports`(`id`) ON DELETE CASCADE ON UPDATE CASCADE; - -ALTER TABLE `reports_users_selection` ADD UNIQUE( `user_id`, `report_id`); \ No newline at end of file diff --git a/database/update/update_084_report_annotation_table.sql b/database/update/update_084_report_annotation_table.sql deleted file mode 100644 index 2f5ba03d..00000000 --- a/database/update/update_084_report_annotation_table.sql +++ /dev/null @@ -1 +0,0 @@ -INSERT INTO `report_perspectives` (`id`, `title`, `description`, `order`) VALUES ('annotation_table', 'Annotation table', 'Display a summary of annotations', '100'); \ No newline at end of file diff --git a/database/update/update_085_tagsets.sql b/database/update/update_085_tagsets.sql deleted file mode 100644 index c5864c80..00000000 --- a/database/update/update_085_tagsets.sql +++ /dev/null @@ -1,2 +0,0 @@ -INSERT INTO `tagsets` (`tagset_id`, `name`) VALUES ('4', 'Hebrew UDPipe'), ('5', 'Russian UDPipe'); -INSERT INTO `tagsets` (`tagset_id`, `name`) VALUES ('6', 'Czech UDPipe'), ('7', 'Bulgarian UDPipe'); \ No newline at end of file diff --git a/database/update/update_086_orths.sql b/database/update/update_086_orths.sql deleted file mode 100644 index e102e8cc..00000000 --- a/database/update/update_086_orths.sql +++ /dev/null @@ -1,34 +0,0 @@ --- --- Struktura tabeli dla tabeli `orths` --- - -CREATE TABLE `orths` ( - `orth_id` bigint(20) NOT NULL, - `orth` varchar(190) NOT NULL -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4_bin; - --- --- Indeksy dla zrzutów tabel --- - --- --- Indexes for table `orths` --- -ALTER TABLE `orths` - ADD PRIMARY KEY (`orth_id`), - ADD KEY `orth` (`orth`); - --- --- AUTO_INCREMENT for dumped tables --- - --- --- AUTO_INCREMENT dla tabeli `orths` --- -ALTER TABLE `orths` - MODIFY `orth_id` bigint(20) NOT NULL AUTO_INCREMENT; - -ALTER TABLE `orths` ADD UNIQUE(`orth`); - -ALTER TABLE `tokens` ADD `orth_id` BIGINT NULL AFTER `eos`; - diff --git a/database/update/update_087_attribute_value_length.sql b/database/update/update_087_attribute_value_length.sql deleted file mode 100644 index 50a4c880..00000000 --- a/database/update/update_087_attribute_value_length.sql +++ /dev/null @@ -1,5 +0,0 @@ -ALTER TABLE `reports_annotations_shared_attributes` CHANGE `value` `value` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL; - -ALTER TABLE `shared_attributes_enum` CHANGE `value` `value` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL; - -ALTER TABLE `shared_attributes_enum` CHANGE `description` `description` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL; \ No newline at end of file diff --git a/database/update/update_088_perspective_annotation_attributes.sql b/database/update/update_088_perspective_annotation_attributes.sql deleted file mode 100644 index 0e639a26..00000000 --- a/database/update/update_088_perspective_annotation_attributes.sql +++ /dev/null @@ -1 +0,0 @@ -INSERT INTO `report_perspectives` (`id`, `title`, `description`, `order`) VALUES ('annotation_attributes', 'Annotation attributes', 'Batch editor of annotation attributes', '110'); \ No newline at end of file diff --git a/database/update/update_089_fix_perspective_id.sql b/database/update/update_089_fix_perspective_id.sql deleted file mode 100644 index 3212fe70..00000000 --- a/database/update/update_089_fix_perspective_id.sql +++ /dev/null @@ -1 +0,0 @@ -UPDATE `report_perspectives` SET `id` = 'importAnnotations' WHERE `report_perspectives`.`id` = 'importannotations'; \ No newline at end of file diff --git a/database/update/update_091_corpus_css.sql b/database/update/update_091_corpus_css.sql deleted file mode 100644 index 0583aecd..00000000 --- a/database/update/update_091_corpus_css.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `corpora` ADD `css` TEXT NULL AFTER `date_created`; \ No newline at end of file diff --git a/database/update/update_092_report_deleted.sql b/database/update/update_092_report_deleted.sql deleted file mode 100644 index e07ef980..00000000 --- a/database/update/update_092_report_deleted.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `reports` ADD `deleted` BOOLEAN NOT NULL DEFAULT FALSE AFTER `parent_report_id`, ADD INDEX `reports_deleted_idx` (`deleted`); \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index bdcc6585..de4fb4eb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,6 +13,7 @@ services: - ./docker/www/config:/home/inforex/config - ./secured_data:/home/inforex/secured_data - ./phpunit:/home/inforex/phpunit + - ./vendor:/home/inforex/vendor depends_on: - db restart: always diff --git a/docker-dev-up.sh b/docker-dev-up.sh index 7ce37345..9f940b24 100755 --- a/docker-dev-up.sh +++ b/docker-dev-up.sh @@ -2,7 +2,7 @@ composer update -AUTOLOAD=engine/include/vendor/autoload.php +AUTOLOAD=vendor/autoload.php if [ -f $AUTOLOAD ]; then docker-compose build @@ -10,4 +10,4 @@ if [ -f $AUTOLOAD ]; then else echo -e "[\e[31mERROR\e[0m] $AUTOLOAD not found" echo -e "Make sure that '\e[32mcomposer\e[0m' is installed in order to run '\e[32mcomposer update\e[0m' and generate $AUTOLOAD" -fi \ No newline at end of file +fi diff --git a/docker/www/Dockerfile b/docker/www/Dockerfile index 544f2957..07e911be 100644 --- a/docker/www/Dockerfile +++ b/docker/www/Dockerfile @@ -1,9 +1,4 @@ -FROM php:5.6-apache as php-base - -# Update stretch repositories moved to archive after 23.04.2023 -RUN sed -i s/deb.debian.org/archive.debian.org/g /etc/apt/sources.list -RUN sed -i 's|security.debian.org|archive.debian.org/|g' /etc/apt/sources.list -RUN sed -i '/stretch-updates/d' /etc/apt/sources.list +FROM php:7.4-apache as php-base RUN apt-get update -y && apt-get upgrade -y RUN apt-get install software-properties-common wget less -y @@ -23,13 +18,13 @@ RUN a2enmod headers RUN a2enmod expires #Installing some PHP libraries -RUN apt-get install libmcrypt-dev zlib1g zlib1g-dev -y \ - && docker-php-ext-install mcrypt \ - && docker-php-ext-install mysql \ - && docker-php-ext-install mysqli \ +RUN apt-get install libmcrypt-dev zlib1g zlib1g-dev -y libzip-dev \ + && docker-php-ext-install mysqli \ && docker-php-ext-install zip \ && docker-php-ext-install gd \ - && apt-get install re2c -y + && apt-get install re2c -y \ + && pecl install mcrypt-1.0.3 \ + && docker-php-ext-enable mcrypt # Xdiff install RUN curl -L -o /tmp/xdiff.tar.gz "http://www.xmailserver.org/libxdiff-0.23.tar.gz" \ @@ -38,11 +33,13 @@ RUN curl -L -o /tmp/xdiff.tar.gz "http://www.xmailserver.org/libxdiff-0.23.tar.g && rm /tmp/xdiff.tar.gz \ && cd /usr/src/xdiff \ && ./configure && make && make install \ - && pecl install xdiff-1.5.2 && docker-php-ext-enable xdiff + && pecl install xdiff-2.0.1 && docker-php-ext-enable xdiff # Supervisor RUN apt-get update -y && apt-get install supervisor -y +# Git +RUN apt-get install git -y FROM php-base @@ -55,7 +52,7 @@ RUN echo " Alias /inforex $inforex_location/public_html\n > /etc/apache2/ports.conf -#Set up symbolic link +#Set up symbolinc link WORKDIR /etc/apache2/sites-enabled/ RUN ln -s ../sites-available/inforex.conf inforex.conf diff --git a/docker/www/php.ini b/docker/www/php.ini index 33068f92..7edb71db 100644 --- a/docker/www/php.ini +++ b/docker/www/php.ini @@ -3,4 +3,4 @@ log_errors = 1 upload_max_filesize = 30M post_max_size = 30M memory_limit = 2048M -max_input_vars = 5000 \ No newline at end of file +max_input_vars = 5000 diff --git a/docker/www/sample.config.local.php b/docker/www/sample.config.local.php index 91d09df6..a8b2d7d0 100644 --- a/docker/www/sample.config.local.php +++ b/docker/www/sample.config.local.php @@ -1,10 +1,12 @@ put_path_engine('/home/inforex/engine'); -Config::Config()->put_path_www('/home/inforex/public_html'); -Config::Config()->put_path_secured_data('/home/inforex/secured_data'); -Config::Config()->put_dsn(array( - 'phptype' => 'mysql', - 'username' => 'inforex', 'port' => '3306', 'password' => 'password', +Config::Cfg()->put_path_engine('/home/inforex/engine'); +Config::Cfg()->put_path_www('/home/inforex/public_html'); +Config::Cfg()->put_path_secured_data('/home/inforex/secured_data'); +Config::Cfg()->put_dsn(array( + 'phptype' => 'mysqli', + 'username' => 'inforex', + 'port' => '3306', + 'password' => 'password', 'hostspec' => 'db', 'database' => 'inforex', )); diff --git a/database/queries/statistics_activity.sql b/documentations/direct.query.examples/statistics_activity.sql similarity index 100% rename from database/queries/statistics_activity.sql rename to documentations/direct.query.examples/statistics_activity.sql diff --git a/engine/config/Config.php b/engine/Config/Config.php similarity index 92% rename from engine/config/Config.php rename to engine/Config/Config.php index 6e93abd4..2787b9fd 100644 --- a/engine/config/Config.php +++ b/engine/Config/Config.php @@ -6,6 +6,11 @@ * See LICENCE */ +// threshold of count types for one set/subset combination +define('MAX_TYPES_LIMIT_THRESHOLD',300); +define('MAX_TYPES_LABEL_INDEX',999999999999); // over autoincrement id +define('MAX_TYPES_NAME_LABEL','...'); + class Phantom { public function __call($name, $arguments) @@ -40,7 +45,7 @@ class Config extends Singleton\Singleton{ "url" => 'http://localhost/inforex', "dsn" => array( - 'phptype' => 'mysql', + 'phptype' => 'mysqli', 'username' => 'inforex', 'password' => 'password', 'hostspec' => 'localhost', @@ -84,16 +89,18 @@ class Config extends Singleton\Singleton{ "log_output" => "fb", "path_grabber" => null, + "max_types_limit_threshold" => MAX_TYPES_LIMIT_THRESHOLD, + // path for local config file - if exists "localConfigFilename" => "" ); // for more friendly call only... - final public static function Config(){ + final public static function Cfg(){ return self::getInstance(); - } // Config() + } // Cfg() // constructor - default values of some parameters final protected function __construct(){ @@ -149,7 +156,9 @@ function __call($method,$arguments){ } } else - call_user_func_array(array($this,"_".$method),$arguments); + if (method_exists($this,$method)) { + call_user_func_array(array($this,"_".$method),$arguments); + } } private function loadOldLocalConfig($pathname) { diff --git a/engine/config/Singleton.php b/engine/Config/Singleton.php similarity index 100% rename from engine/config/Singleton.php rename to engine/Config/Singleton.php diff --git a/engine/actions/a_document_image_upload.php b/engine/actions/a_document_image_upload.php index 9819dc80..ce4a3b4a 100644 --- a/engine/actions/a_document_image_upload.php +++ b/engine/actions/a_document_image_upload.php @@ -37,11 +37,11 @@ function execute(){ $image->setHashName($hashname); $image->save(); - $path = Config::Config()->get_path_secured_data() . "/images" . "/" . $image->getServerFileName(); + $path = Config::Cfg()->get_path_secured_data() . "/images" . "/" . $image->getServerFileName(); DbImage::addImageToReport($report_id, $image->id); - if ( !file_exists(Config::Config()->get_path_secured_data() . "/images") ){ - mkdir(Config::Config()->get_path_secured_data() . "/images", 0755, true); + if ( !file_exists(Config::Cfg()->get_path_secured_data() . "/images") ){ + mkdir(Config::Cfg()->get_path_secured_data() . "/images", 0755, true); } if (move_uploaded_file($_FILES['image']['tmp_name'], $path)) { diff --git a/engine/actions/a_upload.php b/engine/actions/a_upload.php index 7a0e976f..b72a2211 100644 --- a/engine/actions/a_upload.php +++ b/engine/actions/a_upload.php @@ -36,7 +36,7 @@ function execute() return null; } - $newPath = tempnam(Config::Config()->get_path_secured_data(). "/import", "upload_zip_"); + $newPath = tempnam(Config::Cfg()->get_path_secured_data(). "/import", "upload_zip_"); move_uploaded_file($path, $newPath); chmod($newPath, 0755); $params["path"] = $newPath; diff --git a/engine/ajax/ajax_annotation_edit_delete.php b/engine/ajax/ajax_annotation_edit_delete.php index a795c5e7..ca7f1309 100644 --- a/engine/ajax/ajax_annotation_edit_delete.php +++ b/engine/ajax/ajax_annotation_edit_delete.php @@ -16,7 +16,7 @@ function __construct(){ /** * ToDo: implement custom permissions to this action */ - function customPermissionRule($user, $corpus){ + function customPermissionRule($user=null, $corpus=null){ return true; } diff --git a/engine/ajax/ajax_annotation_edit_update.php b/engine/ajax/ajax_annotation_edit_update.php index 99180534..32e9b408 100644 --- a/engine/ajax/ajax_annotation_edit_update.php +++ b/engine/ajax/ajax_annotation_edit_update.php @@ -11,7 +11,7 @@ class Ajax_annotation_edit_update extends CPageCorpus { /** * ToDo: implement custom permissions to this action */ - function customPermissionRule($user, $corpus){ + function customPermissionRule($user=null, $corpus=null){ return true; } diff --git a/engine/ajax/ajax_annotation_type_tree.php b/engine/ajax/ajax_annotation_type_tree.php new file mode 100644 index 00000000..b2836b9b --- /dev/null +++ b/engine/ajax/ajax_annotation_type_tree.php @@ -0,0 +1,18 @@ +status = "new"; $task->save(); - $url = sprintf("%s?page=tasks&corpus=%d&task_id=%d",Config::Config()->get_url(), $corpus->id, $task->task_id); + $url = sprintf("%s?page=tasks&corpus=%d&task_id=%d",Config::Cfg()->get_url(), $corpus->id, $task->task_id); //print(json_encode(array("redirect"=>$url))); //return; diff --git a/engine/ajax/ajax_lps_get_corr_tags.php b/engine/ajax/ajax_lps_get_corr_tags.php index 467d8a7d..b54234c1 100644 --- a/engine/ajax/ajax_lps_get_corr_tags.php +++ b/engine/ajax/ajax_lps_get_corr_tags.php @@ -7,7 +7,7 @@ */ // ToDo: Move common methods to an external file -require_once(Config::Config()->get_path_engine() . "/page/page_lps_stats.php"); +require_once(Config::Cfg()->get_path_engine() . "/page/page_lps_stats.php"); /** */ diff --git a/engine/ajax/ajax_lps_get_interp.php b/engine/ajax/ajax_lps_get_interp.php index 10f38acf..51dced1f 100644 --- a/engine/ajax/ajax_lps_get_interp.php +++ b/engine/ajax/ajax_lps_get_interp.php @@ -7,7 +7,7 @@ */ // ToDo: Move common methods to an external file -require_once(Config::Config()->get_path_engine() . "/page/page_lps_stats.php"); +require_once(Config::Cfg()->get_path_engine() . "/page/page_lps_stats.php"); /** */ diff --git a/engine/ajax/ajax_lps_get_tag_docs.php b/engine/ajax/ajax_lps_get_tag_docs.php index bbcc248b..d0171a96 100644 --- a/engine/ajax/ajax_lps_get_tag_docs.php +++ b/engine/ajax/ajax_lps_get_tag_docs.php @@ -7,7 +7,7 @@ */ // ToDo: Move common methods to an external file -require_once(Config::Config()->get_path_engine() . "/page/page_lps_stats.php"); +require_once(Config::Cfg()->get_path_engine() . "/page/page_lps_stats.php"); /** */ diff --git a/engine/ajax/ajax_lps_validate_xml.php b/engine/ajax/ajax_lps_validate_xml.php index bb943daa..485be401 100644 --- a/engine/ajax/ajax_lps_validate_xml.php +++ b/engine/ajax/ajax_lps_validate_xml.php @@ -29,7 +29,7 @@ function execute(){ $c = new MyDOMDocument(); $c->loadXML($content); - $c->schemaValidate(Config::Config()->get_path_engine()."/resources/lps/lps.xsd"); + $c->schemaValidate(Config::Cfg()->get_path_engine()."/resources/lps/lps.xsd"); return array("errors"=>$c->errors ); } diff --git a/engine/ajax/ajax_ner_process.php b/engine/ajax/ajax_ner_process.php index f75891a2..6f6a456a 100644 --- a/engine/ajax/ajax_ner_process.php +++ b/engine/ajax/ajax_ner_process.php @@ -7,7 +7,7 @@ */ // ToDo: Move common methods to an external file -require_once(Config::Config()->get_path_engine()."/page/page_ner.php"); +require_once(Config::Cfg()->get_path_engine()."/page/page_ner.php"); /** */ @@ -28,7 +28,7 @@ function execute(){ $annotation_types = null; $api = null; - foreach (Config::Config()->get_liner2_api() as $m){ + foreach (Config::Cfg()->get_liner2_api() as $m){ if ($m['wsdl'] == $wsdl && $m['model'] == $model){ if ( isset($m['annotations'] )){ $annotation_types = $m['annotations']; diff --git a/engine/ajax/ajax_nextcloud_import.php b/engine/ajax/ajax_nextcloud_import.php index d0c4e0f8..f46dc5d5 100644 --- a/engine/ajax/ajax_nextcloud_import.php +++ b/engine/ajax/ajax_nextcloud_import.php @@ -67,7 +67,7 @@ function execute(){ $task->status = "new"; $task->save(); - $url = sprintf("%s?page=tasks&corpus=%d&task_id=%d", Config::Config()->get_url(), $corpus->id, $task->task_id); + $url = sprintf("%s?page=tasks&corpus=%d&task_id=%d", Config::Cfg()->get_url(), $corpus->id, $task->task_id); print(json_encode(array("redirect"=>$url))); return; diff --git a/engine/ajax/ajax_report_autoextension_ner_process.php b/engine/ajax/ajax_report_autoextension_ner_process.php index 35d82359..5ff1390b 100644 --- a/engine/ajax/ajax_report_autoextension_ner_process.php +++ b/engine/ajax/ajax_report_autoextension_ner_process.php @@ -7,7 +7,7 @@ */ // ToDo: Move common methods to an external file -require_once(Config::Config()->get_path_engine()."/page/page_ner.php"); +require_once(Config::Cfg()->get_path_engine()."/page/page_ner.php"); /** */ @@ -27,7 +27,7 @@ function execute(){ $models = PerspectiveAutoExtension::getModels(); - $tagger = new WSTagger(Config::Config()->get_takipi_wsdl()); + $tagger = new WSTagger(Config::Cfg()->get_takipi_wsdl()); $tagger->tag($text); $sentences = $tagger->getIOB(); @@ -39,7 +39,7 @@ function execute(){ } $text = $takipiText; - $chunker = new Liner(Config::Config()->get_path_python(), Config::Config()->get_path_liner(), Config::Config()->get_path_liner()."/models/" . $models[$model]['file']); + $chunker = new Liner(Config::Cfg()->get_path_python(), Config::Cfg()->get_path_liner(), Config::Cfg()->get_path_liner()."/models/" . $models[$model]['file']); $htmlStr = new HtmlStr($text, true); $offset = 0; diff --git a/engine/ajax/ajax_report_delete_annotation_relation_anaphora.php b/engine/ajax/ajax_report_delete_annotation_relation_anaphora.php index 554e0e0d..fdd57a65 100644 --- a/engine/ajax/ajax_report_delete_annotation_relation_anaphora.php +++ b/engine/ajax/ajax_report_delete_annotation_relation_anaphora.php @@ -17,7 +17,7 @@ function execute(){ global $user; if (!intval($user['user_id'])){ - throw new Exception("Brak identyfikatora użytkownika"); + throw new GeneralAjaxException("Brak identyfikatora użytkownika"); } $relation_id = intval($_POST['relation_id']); diff --git a/engine/ajax/ajax_report_tokenization_process.php b/engine/ajax/ajax_report_tokenization_process.php index 246b432f..c0e56d08 100644 --- a/engine/ajax/ajax_report_tokenization_process.php +++ b/engine/ajax/ajax_report_tokenization_process.php @@ -8,7 +8,7 @@ // ToDo: Move common methods to an external file // loaded earlier by composer classmap mechanism -//require_once(Config::Config()->get_path_engine()."/page/page_ner.php"); +//require_once(Config::Cfg()->get_path_engine()."/page/page_ner.php"); /** */ diff --git a/engine/ajax/ajax_report_update_annotation.php b/engine/ajax/ajax_report_update_annotation.php index 9c9fa113..65cb15a4 100644 --- a/engine/ajax/ajax_report_update_annotation.php +++ b/engine/ajax/ajax_report_update_annotation.php @@ -44,7 +44,7 @@ function execute(){ DbAnnotation::removeUnusedAnnotationSharedAttributes($annotation_id); } } else { - throw new Exception("An error occurred while saving the annotation"); + throw new GeneralAjaxException("An error occurred while saving the annotation"); return; } @@ -62,7 +62,7 @@ function execute(){ * @param $from * @param $to * @param $type_id - * @throws Exception + * @throws GeneralAjaxException */ function validateText($row, $text, $from, $to, $type_id){ $content = $row['content']; @@ -81,7 +81,7 @@ function validateText($row, $text, $from, $to, $type_id){ "Position: [$from,$to]
" . "Sent phrase: '$text'
" . "Database phrase: '$html_revalidate'"; - throw new Exception($error); + throw new GeneralAjaxException($error); } } diff --git a/engine/ajax/ajax_semquel_get_result.php b/engine/ajax/ajax_semquel_get_result.php index c0becb4e..13d0af53 100644 --- a/engine/ajax/ajax_semquel_get_result.php +++ b/engine/ajax/ajax_semquel_get_result.php @@ -11,7 +11,7 @@ class Ajax_semquel_get_result extends CPage { function execute(){ $ids = $_POST['id_list']; - $db2 = new Database(Config::Config()->get_relation_marks_db()); + $db2 = new Database(Config::Cfg()->get_relation_marks_db()); $sql = " SELECT ans.begin as source_begin, " . " ans.end as source_end, " . diff --git a/engine/ajax/ajax_semquel_get_sql.php b/engine/ajax/ajax_semquel_get_sql.php index 8272b345..db51bc31 100644 --- a/engine/ajax/ajax_semquel_get_sql.php +++ b/engine/ajax/ajax_semquel_get_sql.php @@ -12,7 +12,7 @@ class Ajax_semquel_get_sql extends CPage { function execute(){ $sql = $_POST['semquel']; - $db2 = new Database(Config::Config()->get_relation_marks_db()); + $db2 = new Database(Config::Cfg()->get_relation_marks_db()); return $db2->fetch_rows($sql); } diff --git a/engine/ajax/ajax_semquel_run.php b/engine/ajax/ajax_semquel_run.php index 9ee9ce93..110d997f 100644 --- a/engine/ajax/ajax_semquel_run.php +++ b/engine/ajax/ajax_semquel_run.php @@ -13,7 +13,7 @@ function execute(){ $question = $_POST['question']; $ip = strval($_SERVER['REMOTE_ADDR']); - $db_serel = new Database(Config::Config()->get_dsn_questions(), true); + $db_serel = new Database(Config::Cfg()->get_dsn_questions(), true); $db_serel->execute("INSERT INTO questions (question, ip)" . " VALUES(?, ?)", array($question, $ip)); @@ -24,9 +24,9 @@ function execute(){ $ccl = $liner->chunk($question, "plain:wcrft", "ccl"); $wccl = new Wccl(); - $ccl = $wccl->run($ccl, Config::Config()->get_file_with_rules()); + $ccl = $wccl->run($ccl, Config::Cfg()->get_file_with_rules()); - $semql = new Semql(Config::Config()->get_path_semql()); + $semql = new Semql(Config::Cfg()->get_path_semql()); $json = $semql->analyze($ccl); $json = str_replace('\t\t\t', "", $json); diff --git a/engine/ajax/ajax_task_check_status.php b/engine/ajax/ajax_task_check_status.php index 619a5b45..30f360c2 100644 --- a/engine/ajax/ajax_task_check_status.php +++ b/engine/ajax/ajax_task_check_status.php @@ -39,7 +39,7 @@ function execute(){ $data['documents_status'] = $documents_status; if ($task['type'] == "grab"){ - $task_status_path = Config::Config()->get_path_secured_data()."/grab/{$task_id}/status.txt"; + $task_status_path = Config::Cfg()->get_path_secured_data()."/grab/{$task_id}/status.txt"; if (file_exists($task_status_path)){ $task_status_file = fopen($task_status_path, "r"); $data['grab_status'] = intval(fgets($task_status_file)); diff --git a/engine/ajax/ajax_test_wccl_rules.php b/engine/ajax/ajax_test_wccl_rules.php index ef57413d..21514a85 100644 --- a/engine/ajax/ajax_test_wccl_rules.php +++ b/engine/ajax/ajax_test_wccl_rules.php @@ -8,9 +8,9 @@ function execute(){ $offset = intval($_POST['offset']); $rules = strval($_POST['wccl_rules']); $corpus = intval($_POST['corpus']); - $corpus_path = Config::Config()->get_wccl_match_tester_corpora()[$corpus]["path"]; + $corpus_path = Config::Cfg()->get_wccl_match_tester_corpora()[$corpus]["path"]; - $cmd = "python ".Config::Config()->get_wccl_match_tester_script()." -s %d -o %d -r %s -c %s 2>&1"; + $cmd = "python ".Config::Cfg()->get_wccl_match_tester_script()." -s %d -o %d -r %s -c %s 2>&1"; $cmd = sprintf($cmd, $start, $offset, escapeshellarg($rules), $corpus_path); $output = array(); @@ -18,8 +18,8 @@ function execute(){ $errors = array(); - if (!file_exists(Config::Config()->get_wccl_match_tester_script())) - $errors[] = "Błąd konfiguracji: plik nie istnieje {Config::Config()->get_wccl_match_script()}"; + if (!file_exists(Config::Cfg()->get_wccl_match_tester_script())) + $errors[] = "Błąd konfiguracji: plik nie istnieje {Config::Cfg()->get_wccl_match_script()}"; if (count($output) > 1){ $output_joined = implode($output); diff --git a/engine/ajax/ajax_wccl_match_get_reports_id.php b/engine/ajax/ajax_wccl_match_get_reports_id.php index 7578536c..57c8a688 100644 --- a/engine/ajax/ajax_wccl_match_get_reports_id.php +++ b/engine/ajax/ajax_wccl_match_get_reports_id.php @@ -12,7 +12,7 @@ function execute(){ $reports_id = array(); - $ccl_folder = sprintf("%s/ccls/corpus%04d", Config::Config()->get_path_secured_data(), $corpus['id']); + $ccl_folder = sprintf("%s/ccls/corpus%04d", Config::Cfg()->get_path_secured_data(), $corpus['id']); if ( file_exists($ccl_folder) ){ $files = scandir($ccl_folder); diff --git a/engine/ajax/ajax_wccl_match_run.php b/engine/ajax/ajax_wccl_match_run.php index 791de0ad..7b82ac0d 100644 --- a/engine/ajax/ajax_wccl_match_run.php +++ b/engine/ajax/ajax_wccl_match_run.php @@ -14,9 +14,9 @@ function execute(){ $annotations = strval($_POST['annotations']); $report_id = intval($_POST['report_id']); - $cmd = "python ".Config::Config()->get_wccl_match_script()." -r %s -f %s -a %s 2>&1"; + $cmd = "python ".Config::Cfg()->get_wccl_match_script()." -r %s -f %s -a %s 2>&1"; - $file_path = sprintf("%s/ccls/corpus%04d/%08d.xml", Config::Config()->get_path_secured_data(), $corpus['id'], $report_id); + $file_path = sprintf("%s/ccls/corpus%04d/%08d.xml", Config::Cfg()->get_path_secured_data(), $corpus['id'], $report_id); $cmd = sprintf($cmd, escapeshellarg($rules), $file_path, escapeshellarg($annotations)); fb($cmd); @@ -26,8 +26,8 @@ function execute(){ $errors = array(); - if (!file_exists(Config::Config()->get_wccl_match_script())) - $errors[] = "Błąd konfiguracji: plik nie istnieje ".Config::Config()->get_wccl_match_script(); + if (!file_exists(Config::Cfg()->get_wccl_match_script())) + $errors[] = "Błąd konfiguracji: plik nie istnieje ".Config::Cfg()->get_wccl_match_script(); if (count($output) > 1){ $output_joined = implode($output); diff --git a/engine/cliopt.php b/engine/cliopt.php index 1663d3e2..7c4d0366 100644 --- a/engine/cliopt.php +++ b/engine/cliopt.php @@ -230,7 +230,7 @@ function printHelp(){ } print " [parameters]\n\n"; - if (count($this->executes)){ + if (is_array($this->executes) && count($this->executes)){ print " Sample execute:\n"; foreach ($this->executes as $e){ echo " ".sprintf(" # %s\n", $e[1]); diff --git a/engine/clioptcommon.php b/engine/clioptcommon.php index 882deeca..4065a791 100644 --- a/engine/clioptcommon.php +++ b/engine/clioptcommon.php @@ -9,10 +9,12 @@ class CliOptCommon { static function parseDbParameters($opt, $defaultDsn=array()){ - $dbUser = $defaultDsn['username']; - $dbPass = $defaultDsn['password']; - $dbName = $defaultDsn['database']; - list($dbHost, $dbPort) = explode(":", $defaultDsn['hostspec']); + $dbUser = array_key_exists('username',$defaultDsn) ? $defaultDsn['username'] : ""; + $dbPass = array_key_exists('password',$defaultDsn) ? $defaultDsn['password'] : ""; + $dbName = array_key_exists('database',$defaultDsn) ? $defaultDsn['database'] : ""; + $hostspecArray = array_key_exists('hostspec',$defaultDsn) ? explode(":", $defaultDsn['hostspec']) : array() ; + $dbHost = isset($hostspecArray[0]) ? $hostspecArray[0] : ""; + $dbPort = isset($hostspecArray[1]) ? $hostspecArray[1] : ""; if ( $opt->exists("db-uri")){ $uri = $opt->getRequired("db-uri"); @@ -27,10 +29,13 @@ static function parseDbParameters($opt, $defaultDsn=array()){ } } $dsn = array(); - $dsn['phptype'] = 'mysql'; + $dsn['phptype'] = 'mysqli'; $dsn['username'] = $dbUser; $dsn['password'] = $dbPass; - $dsn['hostspec'] = $dbHost . ":" . $dbPort; + $dsn['hostspec'] = $dbHost; + if($dbPort!="") { + $dsn['hostspec'] .= ":" . $dbPort; + } $dsn['database'] = $dbName; return $dsn; } @@ -140,4 +145,4 @@ static function validateFlags($flags, $corpusId){ } } -} \ No newline at end of file +} diff --git a/engine/external/pear/Auth.php b/engine/external/pear/Auth.php index 648880d1..4f2dd55c 100644 --- a/engine/external/pear/Auth.php +++ b/engine/external/pear/Auth.php @@ -330,7 +330,7 @@ class Auth { * @param boolean Should the login form be displayed if necessary? * @return void */ - function Auth($storageDriver, $options = '', $loginFunction = '', $showLogin = true) + function __construct($storageDriver, $options = '', $loginFunction = '', $showLogin = true) { $this->applyAuthOptions($options); @@ -466,7 +466,7 @@ function &_factory($driver, $options = '') { $storage_class = 'Auth_Container_' . $driver; include_once 'Auth/Container/' . $driver . '.php'; - $obj =& new $storage_class($options); + $obj = new $storage_class($options); return $obj; } diff --git a/engine/external/pear/Auth/Container.php b/engine/external/pear/Auth/Container.php index 5724d7d6..0024099f 100644 --- a/engine/external/pear/Auth/Container.php +++ b/engine/external/pear/Auth/Container.php @@ -63,7 +63,7 @@ class Auth_Container * * @access public */ - function Auth_Container() + function __construct() { } diff --git a/engine/external/pear/Auth/Container/Array.php b/engine/external/pear/Auth/Container/Array.php index 334080cb..d0e63f38 100644 --- a/engine/external/pear/Auth/Container/Array.php +++ b/engine/external/pear/Auth/Container/Array.php @@ -124,9 +124,10 @@ function Auth_Container_Array($data) * * @param string Username * @param string Password + * @param boolean not used, for compatibility with ancestor interface * @return boolean|PEAR_Error Error object or boolean */ - function fetchData($user, $pass) + function fetchData($user, $pass, $isChallengeResponse = false) { $this->log('Auth_Container_Array::fetchData() called.', AUTH_LOG_DEBUG); if ( isset($this->users[$user]) diff --git a/engine/external/pear/Auth/Container/DBLite.php b/engine/external/pear/Auth/Container/DBLite.php index 29961089..2f0f17b2 100644 --- a/engine/external/pear/Auth/Container/DBLite.php +++ b/engine/external/pear/Auth/Container/DBLite.php @@ -120,9 +120,9 @@ function _connect(&$dsn) { $this->log('Auth_Container_DBLite::_connect() called.', AUTH_LOG_DEBUG); if (is_string($dsn) || is_array($dsn)) { - $this->db =& DB::connect($dsn, $this->options['db_options']); + $this->db = DB::connect($dsn, $this->options['db_options']); } elseif (is_subclass_of($dsn, "db_common")) { - $this->db =& $dsn; + $this->db = $dsn; } else { return PEAR::raiseError("Invalid dsn or db object given"); } diff --git a/engine/external/pear/Auth/Container/MDB.php b/engine/external/pear/Auth/Container/MDB.php index 019a122a..a6a92d61 100644 --- a/engine/external/pear/Auth/Container/MDB.php +++ b/engine/external/pear/Auth/Container/MDB.php @@ -111,7 +111,7 @@ function _connect($dsn) { $this->log('Auth_Container_MDB::_connect() called.', AUTH_LOG_DEBUG); if (is_string($dsn) || is_array($dsn)) { - $this->db =& MDB::connect($dsn, $this->options['db_options']); + $this->db = MDB::connect($dsn, $this->options['db_options']); } elseif (is_subclass_of($dsn, 'mdb_common')) { $this->db = $dsn; } elseif (is_object($dsn) && MDB::isError($dsn)) { diff --git a/engine/external/pear/Auth/Container/MDB2.php b/engine/external/pear/Auth/Container/MDB2.php index a3c26b7d..97b320da 100644 --- a/engine/external/pear/Auth/Container/MDB2.php +++ b/engine/external/pear/Auth/Container/MDB2.php @@ -83,7 +83,7 @@ class Auth_Container_MDB2 extends Auth_Container * @param string Connection data or MDB2 object * @return object Returns an error object if something went wrong */ - function Auth_Container_MDB2($dsn) + function __construct($dsn) { $this->_setDefaults(); @@ -111,7 +111,7 @@ function _connect($dsn) { $this->log('Auth_Container_MDB2::_connect() called.', AUTH_LOG_DEBUG); if (is_string($dsn) || is_array($dsn)) { - $this->db =& MDB2::connect($dsn, $this->options['db_options']); + $this->db = MDB2::connect($dsn, $this->options['db_options']); } elseif (is_subclass_of($dsn, 'MDB2_Driver_Common')) { $this->db = $dsn; } elseif (is_object($dsn) && MDB2::isError($dsn)) { diff --git a/engine/external/pear/Auth/Container/NetVPOPMaild.php b/engine/external/pear/Auth/Container/NetVPOPMaild.php index 634fab51..b9d78a13 100644 --- a/engine/external/pear/Auth/Container/NetVPOPMaild.php +++ b/engine/external/pear/Auth/Container/NetVPOPMaild.php @@ -108,7 +108,7 @@ function Auth_Container_Vpopmaild($server=null) function fetchData($username, $password) { $this->log('Auth_Container_Vpopmaild::fetchData() called.', AUTH_LOG_DEBUG); - $vpopmaild =& new Net_Vpopmaild(); + $vpopmaild = new Net_Vpopmaild(); // Connect try { $res = $vpopmaild->connect($this->server, $this->port, $this->method); diff --git a/engine/external/pear/Auth/Container/POP3.php b/engine/external/pear/Auth/Container/POP3.php index 0bfab1b5..5278092d 100644 --- a/engine/external/pear/Auth/Container/POP3.php +++ b/engine/external/pear/Auth/Container/POP3.php @@ -128,7 +128,7 @@ function Auth_Container_POP3($server=null) function fetchData($username, $password) { $this->log('Auth_Container_POP3::fetchData() called.', AUTH_LOG_DEBUG); - $pop3 =& new Net_POP3(); + $pop3 = new Net_POP3(); $res = $pop3->connect($this->server, $this->port, $this->method); if (!$res) { $this->log('Connection to POP3 server failed.', AUTH_LOG_DEBUG); diff --git a/engine/external/pear/Auth/Controller.php b/engine/external/pear/Auth/Controller.php index 92d9f80a..b1c707f8 100644 --- a/engine/external/pear/Auth/Controller.php +++ b/engine/external/pear/Auth/Controller.php @@ -106,7 +106,7 @@ class Auth_Controller */ function Auth_Controller(&$auth_obj, $login='login.php', $default='index.php', $accessList=array()) { - $this->auth =& $auth_obj; + $this->auth = $auth_obj; $this->_loginPage = $login; $this->_defaultPage = $default; @session_start(); diff --git a/engine/external/pear/FirePHPCore/FirePHP.class.php b/engine/external/pear/FirePHPCore/FirePHP.class.php deleted file mode 100644 index 67ef84f4..00000000 --- a/engine/external/pear/FirePHPCore/FirePHP.class.php +++ /dev/null @@ -1,1784 +0,0 @@ - - * @license http://www.opensource.org/licenses/bsd-license.php - * @package FirePHPCore - */ - -/** - * @see http://code.google.com/p/firephp/issues/detail?id=112 - */ -if (!defined('E_STRICT')) { - define('E_STRICT', 2048); -} -if (!defined('E_RECOVERABLE_ERROR')) { - define('E_RECOVERABLE_ERROR', 4096); -} -if (!defined('E_DEPRECATED')) { - define('E_DEPRECATED', 8192); -} -if (!defined('E_USER_DEPRECATED')) { - define('E_USER_DEPRECATED', 16384); -} - -/** - * Sends the given data to the FirePHP Firefox Extension. - * The data can be displayed in the Firebug Console or in the - * "Server" request tab. - * - * For more information see: http://www.firephp.org/ - * - * @copyright Copyright (C) 2007-2009 Christoph Dorn - * @author Christoph Dorn - * @license http://www.opensource.org/licenses/bsd-license.php - * @package FirePHPCore - */ -class FirePHP { - - /** - * FirePHP version - * - * @var string - */ - const VERSION = '0.3'; // @pinf replace '0.3' with '%%package.version%%' - - /** - * Firebug LOG level - * - * Logs a message to firebug console. - * - * @var string - */ - const LOG = 'LOG'; - - /** - * Firebug INFO level - * - * Logs a message to firebug console and displays an info icon before the message. - * - * @var string - */ - const INFO = 'INFO'; - - /** - * Firebug WARN level - * - * Logs a message to firebug console, displays an warning icon before the message and colors the line turquoise. - * - * @var string - */ - const WARN = 'WARN'; - - /** - * Firebug ERROR level - * - * Logs a message to firebug console, displays an error icon before the message and colors the line yellow. Also increments the firebug error count. - * - * @var string - */ - const ERROR = 'ERROR'; - - /** - * Dumps a variable to firebug's server panel - * - * @var string - */ - const DUMP = 'DUMP'; - - /** - * Displays a stack trace in firebug console - * - * @var string - */ - const TRACE = 'TRACE'; - - /** - * Displays an exception in firebug console - * - * Increments the firebug error count. - * - * @var string - */ - const EXCEPTION = 'EXCEPTION'; - - /** - * Displays an table in firebug console - * - * @var string - */ - const TABLE = 'TABLE'; - - /** - * Starts a group in firebug console - * - * @var string - */ - const GROUP_START = 'GROUP_START'; - - /** - * Ends a group in firebug console - * - * @var string - */ - const GROUP_END = 'GROUP_END'; - - /** - * Singleton instance of FirePHP - * - * @var FirePHP - */ - protected static $instance = null; - - /** - * Flag whether we are logging from within the exception handler - * - * @var boolean - */ - protected $inExceptionHandler = false; - - /** - * Flag whether to throw PHP errors that have been converted to ErrorExceptions - * - * @var boolean - */ - protected $throwErrorExceptions = true; - - /** - * Flag whether to convert PHP assertion errors to Exceptions - * - * @var boolean - */ - protected $convertAssertionErrorsToExceptions = true; - - /** - * Flag whether to throw PHP assertion errors that have been converted to Exceptions - * - * @var boolean - */ - protected $throwAssertionExceptions = false; - - /** - * Wildfire protocol message index - * - * @var int - */ - protected $messageIndex = 1; - - /** - * Options for the library - * - * @var array - */ - protected $options = array('maxDepth' => 10, - 'maxObjectDepth' => 5, - 'maxArrayDepth' => 5, - 'useNativeJsonEncode' => true, - 'includeLineNumbers' => true); - - /** - * Filters used to exclude object members when encoding - * - * @var array - */ - protected $objectFilters = array( - 'firephp' => array('objectStack', 'instance', 'json_objectStack'), - 'firephp_test_class' => array('objectStack', 'instance', 'json_objectStack') - ); - - /** - * A stack of objects used to detect recursion during object encoding - * - * @var object - */ - protected $objectStack = array(); - - /** - * Flag to enable/disable logging - * - * @var boolean - */ - protected $enabled = true; - - /** - * The insight console to log to if applicable - * - * @var object - */ - protected $logToInsightConsole = null; - - /** - * When the object gets serialized only include specific object members. - * - * @return array - */ - public function __sleep() - { - return array('options','objectFilters','enabled'); - } - - /** - * Gets singleton instance of FirePHP - * - * @param boolean $AutoCreate - * @return FirePHP - */ - public static function getInstance($AutoCreate = false) - { - if ($AutoCreate===true && !self::$instance) { - self::init(); - } - return self::$instance; - } - - /** - * Creates FirePHP object and stores it for singleton access - * - * @return FirePHP - */ - public static function init() - { - return self::setInstance(new self()); - } - - /** - * Set the instance of the FirePHP singleton - * - * @param FirePHP $instance The FirePHP object instance - * @return FirePHP - */ - public static function setInstance($instance) - { - return self::$instance = $instance; - } - - /** - * Set an Insight console to direct all logging calls to - * - * @param object $console The console object to log to - * @return void - */ - public function setLogToInsightConsole($console) - { - if(is_string($console)) { - if(get_class($this)!='FirePHP_Insight' && !is_subclass_of($this, 'FirePHP_Insight')) { - throw new Exception('FirePHP instance not an instance or subclass of FirePHP_Insight!'); - } - $this->logToInsightConsole = $this->to('request')->console($console); - } else { - $this->logToInsightConsole = $console; - } - } - - /** - * Enable and disable logging to Firebug - * - * @param boolean $Enabled TRUE to enable, FALSE to disable - * @return void - */ - public function setEnabled($Enabled) - { - $this->enabled = $Enabled; - } - - /** - * Check if logging is enabled - * - * @return boolean TRUE if enabled - */ - public function getEnabled() - { - return $this->enabled; - } - - /** - * Specify a filter to be used when encoding an object - * - * Filters are used to exclude object members. - * - * @param string $Class The class name of the object - * @param array $Filter An array of members to exclude - * @return void - */ - public function setObjectFilter($Class, $Filter) - { - $this->objectFilters[strtolower($Class)] = $Filter; - } - - /** - * Set some options for the library - * - * Options: - * - maxDepth: The maximum depth to traverse (default: 10) - * - maxObjectDepth: The maximum depth to traverse objects (default: 5) - * - maxArrayDepth: The maximum depth to traverse arrays (default: 5) - * - useNativeJsonEncode: If true will use json_encode() (default: true) - * - includeLineNumbers: If true will include line numbers and filenames (default: true) - * - * @param array $Options The options to be set - * @return void - */ - public function setOptions($Options) - { - $this->options = array_merge($this->options,$Options); - } - - /** - * Get options from the library - * - * @return array The currently set options - */ - public function getOptions() - { - return $this->options; - } - - /** - * Set an option for the library - * - * @param string $Name - * @param mixed $Value - * @throws Exception - * @return void - */ - public function setOption($Name, $Value) - { - if (!isset($this->options[$Name])) { - throw $this->newException('Unknown option: ' . $Name); - } - $this->options[$Name] = $Value; - } - - /** - * Get an option from the library - * - * @param string $Name - * @throws Exception - * @return mixed - */ - public function getOption($Name) - { - if (!isset($this->options[$Name])) { - throw $this->newException('Unknown option: ' . $Name); - } - return $this->options[$Name]; - } - - /** - * Register FirePHP as your error handler - * - * Will throw exceptions for each php error. - * - * @return mixed Returns a string containing the previously defined error handler (if any) - */ - public function registerErrorHandler($throwErrorExceptions = false) - { - //NOTE: The following errors will not be caught by this error handler: - // E_ERROR, E_PARSE, E_CORE_ERROR, - // E_CORE_WARNING, E_COMPILE_ERROR, - // E_COMPILE_WARNING, E_STRICT - - $this->throwErrorExceptions = $throwErrorExceptions; - - return set_error_handler(array($this,'errorHandler')); - } - - /** - * FirePHP's error handler - * - * Throws exception for each php error that will occur. - * - * @param int $errno - * @param string $errstr - * @param string $errfile - * @param int $errline - * @param array $errcontext - */ - public function errorHandler($errno, $errstr, $errfile, $errline, $errcontext) - { - // Don't throw exception if error reporting is switched off - if (error_reporting() == 0) { - return; - } - // Only throw exceptions for errors we are asking for - if (error_reporting() & $errno) { - - $exception = new ErrorException($errstr, 0, $errno, $errfile, $errline); - if ($this->throwErrorExceptions) { - throw $exception; - } else { - $this->fb($exception); - } - } - } - - /** - * Register FirePHP as your exception handler - * - * @return mixed Returns the name of the previously defined exception handler, - * or NULL on error. - * If no previous handler was defined, NULL is also returned. - */ - public function registerExceptionHandler() - { - return set_exception_handler(array($this,'exceptionHandler')); - } - - /** - * FirePHP's exception handler - * - * Logs all exceptions to your firebug console and then stops the script. - * - * @param Exception $Exception - * @throws Exception - */ - function exceptionHandler($Exception) - { - - $this->inExceptionHandler = true; - - header('HTTP/1.1 500 Internal Server Error'); - - try { - $this->fb($Exception); - } catch (Exception $e) { - echo 'We had an exception: ' . $e; - } - $this->inExceptionHandler = false; - } - - /** - * Register FirePHP driver as your assert callback - * - * @param boolean $convertAssertionErrorsToExceptions - * @param boolean $throwAssertionExceptions - * @return mixed Returns the original setting or FALSE on errors - */ - public function registerAssertionHandler($convertAssertionErrorsToExceptions = true, $throwAssertionExceptions = false) - { - $this->convertAssertionErrorsToExceptions = $convertAssertionErrorsToExceptions; - $this->throwAssertionExceptions = $throwAssertionExceptions; - - if ($throwAssertionExceptions && !$convertAssertionErrorsToExceptions) { - throw $this->newException('Cannot throw assertion exceptions as assertion errors are not being converted to exceptions!'); - } - - return assert_options(ASSERT_CALLBACK, array($this, 'assertionHandler')); - } - - /** - * FirePHP's assertion handler - * - * Logs all assertions to your firebug console and then stops the script. - * - * @param string $file File source of assertion - * @param int $line Line source of assertion - * @param mixed $code Assertion code - */ - public function assertionHandler($file, $line, $code) - { - if ($this->convertAssertionErrorsToExceptions) { - - $exception = new ErrorException('Assertion Failed - Code[ '.$code.' ]', 0, null, $file, $line); - - if ($this->throwAssertionExceptions) { - throw $exception; - } else { - $this->fb($exception); - } - - } else { - $this->fb($code, 'Assertion Failed', FirePHP::ERROR, array('File'=>$file,'Line'=>$line)); - } - } - - /** - * Start a group for following messages. - * - * Options: - * Collapsed: [true|false] - * Color: [#RRGGBB|ColorName] - * - * @param string $Name - * @param array $Options OPTIONAL Instructions on how to log the group - * @return true - * @throws Exception - */ - public function group($Name, $Options = null) - { - - if (!$Name) { - throw $this->newException('You must specify a label for the group!'); - } - - if ($Options) { - if (!is_array($Options)) { - throw $this->newException('Options must be defined as an array!'); - } - if (array_key_exists('Collapsed', $Options)) { - $Options['Collapsed'] = ($Options['Collapsed'])?'true':'false'; - } - } - - return $this->fb(null, $Name, FirePHP::GROUP_START, $Options); - } - - /** - * Ends a group you have started before - * - * @return true - * @throws Exception - */ - public function groupEnd() - { - return $this->fb(null, null, FirePHP::GROUP_END); - } - - /** - * Log object with label to firebug console - * - * @see FirePHP::LOG - * @param mixes $Object - * @param string $Label - * @return true - * @throws Exception - */ - public function log($Object, $Label = null, $Options = array()) - { - return $this->fb($Object, $Label, FirePHP::LOG, $Options); - } - - /** - * Log object with label to firebug console - * - * @see FirePHP::INFO - * @param mixes $Object - * @param string $Label - * @return true - * @throws Exception - */ - public function info($Object, $Label = null, $Options = array()) - { - return $this->fb($Object, $Label, FirePHP::INFO, $Options); - } - - /** - * Log object with label to firebug console - * - * @see FirePHP::WARN - * @param mixes $Object - * @param string $Label - * @return true - * @throws Exception - */ - public function warn($Object, $Label = null, $Options = array()) - { - return $this->fb($Object, $Label, FirePHP::WARN, $Options); - } - - /** - * Log object with label to firebug console - * - * @see FirePHP::ERROR - * @param mixes $Object - * @param string $Label - * @return true - * @throws Exception - */ - public function error($Object, $Label = null, $Options = array()) - { - return $this->fb($Object, $Label, FirePHP::ERROR, $Options); - } - - /** - * Dumps key and variable to firebug server panel - * - * @see FirePHP::DUMP - * @param string $Key - * @param mixed $Variable - * @return true - * @throws Exception - */ - public function dump($Key, $Variable, $Options = array()) - { - if (!is_string($Key)) { - throw $this->newException('Key passed to dump() is not a string'); - } - if (strlen($Key)>100) { - throw $this->newException('Key passed to dump() is longer than 100 characters'); - } - if (!preg_match_all('/^[a-zA-Z0-9-_\.:]*$/', $Key, $m)) { - throw $this->newException('Key passed to dump() contains invalid characters [a-zA-Z0-9-_\.:]'); - } - return $this->fb($Variable, $Key, FirePHP::DUMP, $Options); - } - - /** - * Log a trace in the firebug console - * - * @see FirePHP::TRACE - * @param string $Label - * @return true - * @throws Exception - */ - public function trace($Label) - { - return $this->fb($Label, FirePHP::TRACE); - } - - /** - * Log a table in the firebug console - * - * @see FirePHP::TABLE - * @param string $Label - * @param string $Table - * @return true - * @throws Exception - */ - public function table($Label, $Table, $Options = array()) - { - return $this->fb($Table, $Label, FirePHP::TABLE, $Options); - } - - /** - * Insight API wrapper - * - * @see Insight_Helper::to() - */ - public static function to() - { - $instance = self::getInstance(); - if (!method_exists($instance, "_to")) { - throw new Exception("FirePHP::to() implementation not loaded"); - } - $args = func_get_args(); - return call_user_func_array(array($instance, '_to'), $args); - } - - /** - * Insight API wrapper - * - * @see Insight_Helper::plugin() - */ - public static function plugin() - { - $instance = self::getInstance(); - if (!method_exists($instance, "_plugin")) { - throw new Exception("FirePHP::plugin() implementation not loaded"); - } - $args = func_get_args(); - return call_user_func_array(array($instance, '_plugin'), $args); - } - - /** - * Check if FirePHP is installed on client - * - * @return boolean - */ - public function detectClientExtension() - { - // Check if FirePHP is installed on client via User-Agent header - if (@preg_match_all('/\sFirePHP\/([\.\d]*)\s?/si',$this->getUserAgent(),$m) && - version_compare($m[1][0],'0.0.6','>=')) { - return true; - } else - // Check if FirePHP is installed on client via X-FirePHP-Version header - if (@preg_match_all('/^([\.\d]*)$/si',$this->getRequestHeader("X-FirePHP-Version"),$m) && - version_compare($m[1][0],'0.0.6','>=')) { - return true; - } - return false; - } - - /** - * Log varible to Firebug - * - * @see http://www.firephp.org/Wiki/Reference/Fb - * @param mixed $Object The variable to be logged - * @return true Return TRUE if message was added to headers, FALSE otherwise - * @throws Exception - */ - public function fb($Object) - { - if($this instanceof FirePHP_Insight && method_exists($this, '_logUpgradeClientMessage')) { - if(!FirePHP_Insight::$upgradeClientMessageLogged) { // avoid infinite recursion as _logUpgradeClientMessage() logs a message - $this->_logUpgradeClientMessage(); - } - } - - static $insightGroupStack = array(); - - if (!$this->getEnabled()) { - return false; - } - - if ($this->headersSent($filename, $linenum)) { - // If we are logging from within the exception handler we cannot throw another exception - if ($this->inExceptionHandler) { - // Simply echo the error out to the page - echo '
FirePHP ERROR: Headers already sent in '.$filename.' on line '.$linenum.'. Cannot send log data to FirePHP. You must have Output Buffering enabled via ob_start() or output_buffering ini directive.
'; - } else { - throw $this->newException('Headers already sent in '.$filename.' on line '.$linenum.'. Cannot send log data to FirePHP. You must have Output Buffering enabled via ob_start() or output_buffering ini directive.'); - } - } - - $Type = null; - $Label = null; - $Options = array(); - - if (func_num_args()==1) { - } else - if (func_num_args()==2) { - switch(func_get_arg(1)) { - case self::LOG: - case self::INFO: - case self::WARN: - case self::ERROR: - case self::DUMP: - case self::TRACE: - case self::EXCEPTION: - case self::TABLE: - case self::GROUP_START: - case self::GROUP_END: - $Type = func_get_arg(1); - break; - default: - $Label = func_get_arg(1); - break; - } - } else - if (func_num_args()==3) { - $Type = func_get_arg(2); - $Label = func_get_arg(1); - } else - if (func_num_args()==4) { - $Type = func_get_arg(2); - $Label = func_get_arg(1); - $Options = func_get_arg(3); - } else { - throw $this->newException('Wrong number of arguments to fb() function!'); - } - - if($this->logToInsightConsole!==null && (get_class($this)=='FirePHP_Insight' || is_subclass_of($this, 'FirePHP_Insight'))) { - $msg = $this->logToInsightConsole; - if ($Object instanceof Exception) { - $Type = self::EXCEPTION; - } - if($Label && $Type!=self::TABLE && $Type!=self::GROUP_START) { - $msg = $msg->label($Label); - } - switch($Type) { - case self::DUMP: - case self::LOG: - return $msg->log($Object); - case self::INFO: - return $msg->info($Object); - case self::WARN: - return $msg->warn($Object); - case self::ERROR: - return $msg->error($Object); - case self::TRACE: - return $msg->trace($Object); - case self::EXCEPTION: - return $this->plugin('engine')->handleException($Object, $msg); - case self::TABLE: - if (isset($Object[0]) && !is_string($Object[0]) && $Label) { - $Object = array($Label, $Object); - } - return $msg->table($Object[0], array_slice($Object[1],1), $Object[1][0]); - case self::GROUP_START: - $insightGroupStack[] = $msg->group(md5($Label))->open(); - return $msg->log($Label); - case self::GROUP_END: - if(count($insightGroupStack)==0) { - throw new Error('Too many groupEnd() as opposed to group() calls!'); - } - $group = array_pop($insightGroupStack); - return $group->close(); - default: - return $msg->log($Object); - } - } - - if (!$this->detectClientExtension()) { - return false; - } - - $meta = array(); - $skipFinalObjectEncode = false; - - if ($Object instanceof Exception) { - - $meta['file'] = $this->_escapeTraceFile($Object->getFile()); - $meta['line'] = $Object->getLine(); - - $trace = $Object->getTrace(); - if ($Object instanceof ErrorException - && isset($trace[0]['function']) - && $trace[0]['function']=='errorHandler' - && isset($trace[0]['class']) - && $trace[0]['class']=='FirePHP') { - - $severity = false; - switch($Object->getSeverity()) { - case E_WARNING: $severity = 'E_WARNING'; break; - case E_NOTICE: $severity = 'E_NOTICE'; break; - case E_USER_ERROR: $severity = 'E_USER_ERROR'; break; - case E_USER_WARNING: $severity = 'E_USER_WARNING'; break; - case E_USER_NOTICE: $severity = 'E_USER_NOTICE'; break; - case E_STRICT: $severity = 'E_STRICT'; break; - case E_RECOVERABLE_ERROR: $severity = 'E_RECOVERABLE_ERROR'; break; - case E_DEPRECATED: $severity = 'E_DEPRECATED'; break; - case E_USER_DEPRECATED: $severity = 'E_USER_DEPRECATED'; break; - } - - $Object = array('Class'=>get_class($Object), - 'Message'=>$severity.': '.$Object->getMessage(), - 'File'=>$this->_escapeTraceFile($Object->getFile()), - 'Line'=>$Object->getLine(), - 'Type'=>'trigger', - 'Trace'=>$this->_escapeTrace(array_splice($trace,2))); - $skipFinalObjectEncode = true; - } else { - $Object = array('Class'=>get_class($Object), - 'Message'=>$Object->getMessage(), - 'File'=>$this->_escapeTraceFile($Object->getFile()), - 'Line'=>$Object->getLine(), - 'Type'=>'throw', - 'Trace'=>$this->_escapeTrace($trace)); - $skipFinalObjectEncode = true; - } - $Type = self::EXCEPTION; - - } else - if ($Type==self::TRACE) { - - $trace = debug_backtrace(); - if (!$trace) return false; - for( $i=0 ; $i_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php' - || substr($this->_standardizePath($trace[$i]['file']),-29,29)=='FirePHPCore/FirePHP.class.php')) { - /* Skip - FB::trace(), FB::send(), $firephp->trace(), $firephp->fb() */ - } else - if (isset($trace[$i]['class']) - && isset($trace[$i+1]['file']) - && $trace[$i]['class']=='FirePHP' - && substr($this->_standardizePath($trace[$i+1]['file']),-18,18)=='FirePHPCore/fb.php') { - /* Skip fb() */ - } else - if ($trace[$i]['function']=='fb' - || $trace[$i]['function']=='trace' - || $trace[$i]['function']=='send') { - - $Object = array('Class'=>isset($trace[$i]['class'])?$trace[$i]['class']:'', - 'Type'=>isset($trace[$i]['type'])?$trace[$i]['type']:'', - 'Function'=>isset($trace[$i]['function'])?$trace[$i]['function']:'', - 'Message'=>$trace[$i]['args'][0], - 'File'=>isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):'', - 'Line'=>isset($trace[$i]['line'])?$trace[$i]['line']:'', - 'Args'=>isset($trace[$i]['args'])?$this->encodeObject($trace[$i]['args']):'', - 'Trace'=>$this->_escapeTrace(array_splice($trace,$i+1))); - - $skipFinalObjectEncode = true; - $meta['file'] = isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):''; - $meta['line'] = isset($trace[$i]['line'])?$trace[$i]['line']:''; - break; - } - } - - } else - if ($Type==self::TABLE) { - - if (isset($Object[0]) && is_string($Object[0])) { - $Object[1] = $this->encodeTable($Object[1]); - } else { - $Object = $this->encodeTable($Object); - } - - $skipFinalObjectEncode = true; - - } else - if ($Type==self::GROUP_START) { - - if (!$Label) { - throw $this->newException('You must specify a label for the group!'); - } - - } else { - if ($Type===null) { - $Type = self::LOG; - } - } - - if ($this->options['includeLineNumbers']) { - if (!isset($meta['file']) || !isset($meta['line'])) { - - $trace = debug_backtrace(); - for( $i=0 ; $trace && $i_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php' - || substr($this->_standardizePath($trace[$i]['file']),-29,29)=='FirePHPCore/FirePHP.class.php')) { - /* Skip - FB::trace(), FB::send(), $firephp->trace(), $firephp->fb() */ - } else - if (isset($trace[$i]['class']) - && isset($trace[$i+1]['file']) - && $trace[$i]['class']=='FirePHP' - && substr($this->_standardizePath($trace[$i+1]['file']),-18,18)=='FirePHPCore/fb.php') { - /* Skip fb() */ - } else - if (isset($trace[$i]['file']) - && substr($this->_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php') { - /* Skip FB::fb() */ - } else { - $meta['file'] = isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):''; - $meta['line'] = isset($trace[$i]['line'])?$trace[$i]['line']:''; - break; - } - } - } - } else { - unset($meta['file']); - unset($meta['line']); - } - - $this->setHeader('X-Wf-Protocol-1','http://meta.wildfirehq.org/Protocol/JsonStream/0.2'); - $this->setHeader('X-Wf-1-Plugin-1','http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/'.self::VERSION); - - $structure_index = 1; - if ($Type==self::DUMP) { - $structure_index = 2; - $this->setHeader('X-Wf-1-Structure-2','http://meta.firephp.org/Wildfire/Structure/FirePHP/Dump/0.1'); - } else { - $this->setHeader('X-Wf-1-Structure-1','http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1'); - } - - if ($Type==self::DUMP) { - $msg = '{"'.$Label.'":'.$this->jsonEncode($Object, $skipFinalObjectEncode).'}'; - } else { - $msg_meta = $Options; - $msg_meta['Type'] = $Type; - if ($Label!==null) { - $msg_meta['Label'] = $Label; - } - if (isset($meta['file']) && !isset($msg_meta['File'])) { - $msg_meta['File'] = $meta['file']; - } - if (isset($meta['line']) && !isset($msg_meta['Line'])) { - $msg_meta['Line'] = $meta['line']; - } - $msg = '['.$this->jsonEncode($msg_meta).','.$this->jsonEncode($Object, $skipFinalObjectEncode).']'; - } - - $parts = explode("\n",chunk_split($msg, 5000, "\n")); - - for( $i=0 ; $i2) { - // Message needs to be split into multiple parts - $this->setHeader('X-Wf-1-'.$structure_index.'-'.'1-'.$this->messageIndex, - (($i==0)?strlen($msg):'') - . '|' . $part . '|' - . (($isetHeader('X-Wf-1-'.$structure_index.'-'.'1-'.$this->messageIndex, - strlen($part) . '|' . $part . '|'); - } - - $this->messageIndex++; - - if ($this->messageIndex > 99999) { - throw $this->newException('Maximum number (99,999) of messages reached!'); - } - } - } - - $this->setHeader('X-Wf-1-Index',$this->messageIndex-1); - - return true; - } - - /** - * Standardizes path for windows systems. - * - * @param string $Path - * @return string - */ - protected function _standardizePath($Path) - { - return preg_replace('/\\\\+/','/',$Path); - } - - /** - * Escape trace path for windows systems - * - * @param array $Trace - * @return array - */ - protected function _escapeTrace($Trace) - { - if (!$Trace) return $Trace; - for( $i=0 ; $i_escapeTraceFile($Trace[$i]['file']); - } - if (isset($Trace[$i]['args'])) { - $Trace[$i]['args'] = $this->encodeObject($Trace[$i]['args']); - } - } - return $Trace; - } - - /** - * Escape file information of trace for windows systems - * - * @param string $File - * @return string - */ - protected function _escapeTraceFile($File) - { - /* Check if we have a windows filepath */ - if (strpos($File,'\\')) { - /* First strip down to single \ */ - - $file = preg_replace('/\\\\+/','\\',$File); - - return $file; - } - return $File; - } - - /** - * Check if headers have already been sent - * - * @param string $Filename - * @param integer $Linenum - */ - protected function headersSent(&$Filename, &$Linenum) - { - return headers_sent($Filename, $Linenum); - } - - /** - * Send header - * - * @param string $Name - * @param string $Value - */ - protected function setHeader($Name, $Value) - { - return header($Name.': '.$Value); - } - - /** - * Get user agent - * - * @return string|false - */ - protected function getUserAgent() - { - if (!isset($_SERVER['HTTP_USER_AGENT'])) return false; - return $_SERVER['HTTP_USER_AGENT']; - } - - /** - * Get all request headers - * - * @return array - */ - public static function getAllRequestHeaders() { - static $_cached_headers = false; - if($_cached_headers!==false) { - return $_cached_headers; - } - $headers = array(); - if(function_exists('getallheaders')) { - foreach( getallheaders() as $name => $value ) { - $headers[strtolower($name)] = $value; - } - } else { - foreach($_SERVER as $name => $value) { - if(substr($name, 0, 5) == 'HTTP_') { - $headers[strtolower(str_replace(' ', '-', str_replace('_', ' ', substr($name, 5))))] = $value; - } - } - } - return $_cached_headers = $headers; - } - - /** - * Get a request header - * - * @return string|false - */ - protected function getRequestHeader($Name) - { - $headers = self::getAllRequestHeaders(); - if (isset($headers[strtolower($Name)])) { - return $headers[strtolower($Name)]; - } - return false; - } - - /** - * Returns a new exception - * - * @param string $Message - * @return Exception - */ - protected function newException($Message) - { - return new Exception($Message); - } - - /** - * Encode an object into a JSON string - * - * Uses PHP's jeson_encode() if available - * - * @param object $Object The object to be encoded - * @return string The JSON string - */ - public function jsonEncode($Object, $skipObjectEncode = false) - { - if (!$skipObjectEncode) { - $Object = $this->encodeObject($Object); - } - - if (function_exists('json_encode') - && $this->options['useNativeJsonEncode']!=false) { - - return json_encode($Object); - } else { - return $this->json_encode($Object); - } - } - - /** - * Encodes a table by encoding each row and column with encodeObject() - * - * @param array $Table The table to be encoded - * @return array - */ - protected function encodeTable($Table) - { - - if (!$Table) return $Table; - - $new_table = array(); - foreach($Table as $row) { - - if (is_array($row)) { - $new_row = array(); - - foreach($row as $item) { - $new_row[] = $this->encodeObject($item); - } - - $new_table[] = $new_row; - } - } - - return $new_table; - } - - /** - * Encodes an object including members with - * protected and private visibility - * - * @param Object $Object The object to be encoded - * @param int $Depth The current traversal depth - * @return array All members of the object - */ - protected function encodeObject($Object, $ObjectDepth = 1, $ArrayDepth = 1, $MaxDepth = 1) - { - if ($MaxDepth > $this->options['maxDepth']) { - return '** Max Depth ('.$this->options['maxDepth'].') **'; - } - - $return = array(); - - if (is_resource($Object)) { - - return '** '.(string)$Object.' **'; - - } else - if (is_object($Object)) { - - if ($ObjectDepth > $this->options['maxObjectDepth']) { - return '** Max Object Depth ('.$this->options['maxObjectDepth'].') **'; - } - - foreach ($this->objectStack as $refVal) { - if ($refVal === $Object) { - return '** Recursion ('.get_class($Object).') **'; - } - } - array_push($this->objectStack, $Object); - - $return['__className'] = $class = get_class($Object); - $class_lower = strtolower($class); - - $reflectionClass = new ReflectionClass($class); - $properties = array(); - foreach( $reflectionClass->getProperties() as $property) { - $properties[$property->getName()] = $property; - } - - $members = (array)$Object; - - foreach( $properties as $plain_name => $property ) { - - $name = $raw_name = $plain_name; - if ($property->isStatic()) { - $name = 'static:'.$name; - } - if ($property->isPublic()) { - $name = 'public:'.$name; - } else - if ($property->isPrivate()) { - $name = 'private:'.$name; - $raw_name = "\0".$class."\0".$raw_name; - } else - if ($property->isProtected()) { - $name = 'protected:'.$name; - $raw_name = "\0".'*'."\0".$raw_name; - } - - if (!(isset($this->objectFilters[$class_lower]) - && is_array($this->objectFilters[$class_lower]) - && in_array($plain_name,$this->objectFilters[$class_lower]))) { - - if (array_key_exists($raw_name,$members) - && !$property->isStatic()) { - - $return[$name] = $this->encodeObject($members[$raw_name], $ObjectDepth + 1, 1, $MaxDepth + 1); - - } else { - if (method_exists($property,'setAccessible')) { - $property->setAccessible(true); - $return[$name] = $this->encodeObject($property->getValue($Object), $ObjectDepth + 1, 1, $MaxDepth + 1); - } else - if ($property->isPublic()) { - $return[$name] = $this->encodeObject($property->getValue($Object), $ObjectDepth + 1, 1, $MaxDepth + 1); - } else { - $return[$name] = '** Need PHP 5.3 to get value **'; - } - } - } else { - $return[$name] = '** Excluded by Filter **'; - } - } - - // Include all members that are not defined in the class - // but exist in the object - foreach( $members as $raw_name => $value ) { - - $name = $raw_name; - - if ($name{0} == "\0") { - $parts = explode("\0", $name); - $name = $parts[2]; - } - - $plain_name = $name; - - if (!isset($properties[$name])) { - $name = 'undeclared:'.$name; - - if (!(isset($this->objectFilters[$class_lower]) - && is_array($this->objectFilters[$class_lower]) - && in_array($plain_name,$this->objectFilters[$class_lower]))) { - - $return[$name] = $this->encodeObject($value, $ObjectDepth + 1, 1, $MaxDepth + 1); - } else { - $return[$name] = '** Excluded by Filter **'; - } - } - } - - array_pop($this->objectStack); - - } elseif (is_array($Object)) { - - if ($ArrayDepth > $this->options['maxArrayDepth']) { - return '** Max Array Depth ('.$this->options['maxArrayDepth'].') **'; - } - - foreach ($Object as $key => $val) { - - // Encoding the $GLOBALS PHP array causes an infinite loop - // if the recursion is not reset here as it contains - // a reference to itself. This is the only way I have come up - // with to stop infinite recursion in this case. - if ($key=='GLOBALS' - && is_array($val) - && array_key_exists('GLOBALS',$val)) { - $val['GLOBALS'] = '** Recursion (GLOBALS) **'; - } - - $return[$key] = $this->encodeObject($val, 1, $ArrayDepth + 1, $MaxDepth + 1); - } - } else { - if (self::is_utf8($Object)) { - return $Object; - } else { - return utf8_encode($Object); - } - } - return $return; - } - - /** - * Returns true if $string is valid UTF-8 and false otherwise. - * - * @param mixed $str String to be tested - * @return boolean - */ - protected static function is_utf8($str) - { - if(function_exists('mb_detect_encoding')) { - return (mb_detect_encoding($str) == 'UTF-8'); - } - $c=0; $b=0; - $bits=0; - $len=strlen($str); - for($i=0; $i<$len; $i++){ - $c=ord($str[$i]); - if ($c > 128){ - if (($c >= 254)) return false; - elseif ($c >= 252) $bits=6; - elseif ($c >= 248) $bits=5; - elseif ($c >= 240) $bits=4; - elseif ($c >= 224) $bits=3; - elseif ($c >= 192) $bits=2; - else return false; - if (($i+$bits) > $len) return false; - while($bits > 1){ - $i++; - $b=ord($str[$i]); - if ($b < 128 || $b > 191) return false; - $bits--; - } - } - } - return true; - } - - /** - * Converts to and from JSON format. - * - * JSON (JavaScript Object Notation) is a lightweight data-interchange - * format. It is easy for humans to read and write. It is easy for machines - * to parse and generate. It is based on a subset of the JavaScript - * Programming Language, Standard ECMA-262 3rd Edition - December 1999. - * This feature can also be found in Python. JSON is a text format that is - * completely language independent but uses conventions that are familiar - * to programmers of the C-family of languages, including C, C++, C#, Java, - * JavaScript, Perl, TCL, and many others. These properties make JSON an - * ideal data-interchange language. - * - * This package provides a simple encoder and decoder for JSON notation. It - * is intended for use with client-side Javascript applications that make - * use of HTTPRequest to perform server communication functions - data can - * be encoded into JSON notation for use in a client-side javascript, or - * decoded from incoming Javascript requests. JSON format is native to - * Javascript, and can be directly eval()'ed with no further parsing - * overhead - * - * All strings should be in ASCII or UTF-8 format! - * - * LICENSE: Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: Redistributions of source code must retain the - * above copyright notice, this list of conditions and the following - * disclaimer. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * @category - * @package Services_JSON - * @author Michal Migurski - * @author Matt Knapp - * @author Brett Stimmerman - * @author Christoph Dorn - * @copyright 2005 Michal Migurski - * @version CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $ - * @license http://www.opensource.org/licenses/bsd-license.php - * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 - */ - - - /** - * Keep a list of objects as we descend into the array so we can detect recursion. - */ - private $json_objectStack = array(); - - - /** - * convert a string from one UTF-8 char to one UTF-16 char - * - * Normally should be handled by mb_convert_encoding, but - * provides a slower PHP-only method for installations - * that lack the multibye string extension. - * - * @param string $utf8 UTF-8 character - * @return string UTF-16 character - * @access private - */ - private function json_utf82utf16($utf8) - { - // oh please oh please oh please oh please oh please - if (function_exists('mb_convert_encoding')) { - return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8'); - } - - switch(strlen($utf8)) { - case 1: - // this case should never be reached, because we are in ASCII range - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return $utf8; - - case 2: - // return a UTF-16 character from a 2-byte UTF-8 char - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return chr(0x07 & (ord($utf8{0}) >> 2)) - . chr((0xC0 & (ord($utf8{0}) << 6)) - | (0x3F & ord($utf8{1}))); - - case 3: - // return a UTF-16 character from a 3-byte UTF-8 char - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return chr((0xF0 & (ord($utf8{0}) << 4)) - | (0x0F & (ord($utf8{1}) >> 2))) - . chr((0xC0 & (ord($utf8{1}) << 6)) - | (0x7F & ord($utf8{2}))); - } - - // ignoring UTF-32 for now, sorry - return ''; - } - - /** - * encodes an arbitrary variable into JSON format - * - * @param mixed $var any number, boolean, string, array, or object to be encoded. - * see argument 1 to Services_JSON() above for array-parsing behavior. - * if var is a strng, note that encode() always expects it - * to be in ASCII or UTF-8 format! - * - * @return mixed JSON string representation of input var or an error if a problem occurs - * @access public - */ - private function json_encode($var) - { - - if (is_object($var)) { - if (in_array($var,$this->json_objectStack)) { - return '"** Recursion **"'; - } - } - - switch (gettype($var)) { - case 'boolean': - return $var ? 'true' : 'false'; - - case 'NULL': - return 'null'; - - case 'integer': - return (int) $var; - - case 'double': - case 'float': - return (float) $var; - - case 'string': - // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT - $ascii = ''; - $strlen_var = strlen($var); - - /* - * Iterate over every character in the string, - * escaping with a slash or encoding to UTF-8 where necessary - */ - for ($c = 0; $c < $strlen_var; ++$c) { - - $ord_var_c = ord($var{$c}); - - switch (true) { - case $ord_var_c == 0x08: - $ascii .= '\b'; - break; - case $ord_var_c == 0x09: - $ascii .= '\t'; - break; - case $ord_var_c == 0x0A: - $ascii .= '\n'; - break; - case $ord_var_c == 0x0C: - $ascii .= '\f'; - break; - case $ord_var_c == 0x0D: - $ascii .= '\r'; - break; - - case $ord_var_c == 0x22: - case $ord_var_c == 0x2F: - case $ord_var_c == 0x5C: - // double quote, slash, slosh - $ascii .= '\\'.$var{$c}; - break; - - case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): - // characters U-00000000 - U-0000007F (same as ASCII) - $ascii .= $var{$c}; - break; - - case (($ord_var_c & 0xE0) == 0xC0): - // characters U-00000080 - U-000007FF, mask 110XXXXX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, ord($var{$c + 1})); - $c += 1; - $utf16 = $this->json_utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - - case (($ord_var_c & 0xF0) == 0xE0): - // characters U-00000800 - U-0000FFFF, mask 1110XXXX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, - ord($var{$c + 1}), - ord($var{$c + 2})); - $c += 2; - $utf16 = $this->json_utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - - case (($ord_var_c & 0xF8) == 0xF0): - // characters U-00010000 - U-001FFFFF, mask 11110XXX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, - ord($var{$c + 1}), - ord($var{$c + 2}), - ord($var{$c + 3})); - $c += 3; - $utf16 = $this->json_utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - - case (($ord_var_c & 0xFC) == 0xF8): - // characters U-00200000 - U-03FFFFFF, mask 111110XX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, - ord($var{$c + 1}), - ord($var{$c + 2}), - ord($var{$c + 3}), - ord($var{$c + 4})); - $c += 4; - $utf16 = $this->json_utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - - case (($ord_var_c & 0xFE) == 0xFC): - // characters U-04000000 - U-7FFFFFFF, mask 1111110X - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, - ord($var{$c + 1}), - ord($var{$c + 2}), - ord($var{$c + 3}), - ord($var{$c + 4}), - ord($var{$c + 5})); - $c += 5; - $utf16 = $this->json_utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - } - } - - return '"'.$ascii.'"'; - - case 'array': - /* - * As per JSON spec if any array key is not an integer - * we must treat the the whole array as an object. We - * also try to catch a sparsely populated associative - * array with numeric keys here because some JS engines - * will create an array with empty indexes up to - * max_index which can cause memory issues and because - * the keys, which may be relevant, will be remapped - * otherwise. - * - * As per the ECMA and JSON specification an object may - * have any string as a property. Unfortunately due to - * a hole in the ECMA specification if the key is a - * ECMA reserved word or starts with a digit the - * parameter is only accessible using ECMAScript's - * bracket notation. - */ - - // treat as a JSON object - if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { - - $this->json_objectStack[] = $var; - - $properties = array_map(array($this, 'json_name_value'), - array_keys($var), - array_values($var)); - - array_pop($this->json_objectStack); - - foreach($properties as $property) { - if ($property instanceof Exception) { - return $property; - } - } - - return '{' . join(',', $properties) . '}'; - } - - $this->json_objectStack[] = $var; - - // treat it like a regular array - $elements = array_map(array($this, 'json_encode'), $var); - - array_pop($this->json_objectStack); - - foreach($elements as $element) { - if ($element instanceof Exception) { - return $element; - } - } - - return '[' . join(',', $elements) . ']'; - - case 'object': - $vars = self::encodeObject($var); - - $this->json_objectStack[] = $var; - - $properties = array_map(array($this, 'json_name_value'), - array_keys($vars), - array_values($vars)); - - array_pop($this->json_objectStack); - - foreach($properties as $property) { - if ($property instanceof Exception) { - return $property; - } - } - - return '{' . join(',', $properties) . '}'; - - default: - return null; - } - } - - /** - * array-walking function for use in generating JSON-formatted name-value pairs - * - * @param string $name name of key to use - * @param mixed $value reference to an array element to be encoded - * - * @return string JSON-formatted name-value pair, like '"name":value' - * @access private - */ - private function json_name_value($name, $value) - { - // Encoding the $GLOBALS PHP array causes an infinite loop - // if the recursion is not reset here as it contains - // a reference to itself. This is the only way I have come up - // with to stop infinite recursion in this case. - if ($name=='GLOBALS' - && is_array($value) - && array_key_exists('GLOBALS',$value)) { - $value['GLOBALS'] = '** Recursion **'; - } - - $encoded_value = $this->json_encode($value); - - if ($encoded_value instanceof Exception) { - return $encoded_value; - } - - return $this->json_encode(strval($name)) . ':' . $encoded_value; - } - - /** - * @deprecated - */ - public function setProcessorUrl($URL) - { - trigger_error("The FirePHP::setProcessorUrl() method is no longer supported", E_USER_DEPRECATED); - } - - /** - * @deprecated - */ - public function setRendererUrl($URL) - { - trigger_error("The FirePHP::setRendererUrl() method is no longer supported", E_USER_DEPRECATED); - } -} diff --git a/engine/external/pear/FirePHPCore/FirePHP.class.php4 b/engine/external/pear/FirePHPCore/FirePHP.class.php4 deleted file mode 100644 index 407a6596..00000000 --- a/engine/external/pear/FirePHPCore/FirePHP.class.php4 +++ /dev/null @@ -1,1332 +0,0 @@ - - * @author Michael Day - * @license http://www.opensource.org/licenses/bsd-license.php - * @package FirePHPCore - */ - -/** - * FirePHP version - * - * @var string - */ -define('FirePHP_VERSION', '0.3'); // @pinf replace '0.3' with '%%package.version%%' - -/** - * Firebug LOG level - * - * Logs a message to firebug console - * - * @var string - */ -define('FirePHP_LOG', 'LOG'); - -/** - * Firebug INFO level - * - * Logs a message to firebug console and displays an info icon before the message - * - * @var string - */ -define('FirePHP_INFO', 'INFO'); - -/** - * Firebug WARN level - * - * Logs a message to firebug console, displays a warning icon before the message and colors the line turquoise - * - * @var string - */ -define('FirePHP_WARN', 'WARN'); - -/** - * Firebug ERROR level - * - * Logs a message to firebug console, displays an error icon before the message and colors the line yellow. Also increments the firebug error count. - * - * @var string - */ -define('FirePHP_ERROR', 'ERROR'); - -/** - * Dumps a variable to firebug's server panel - * - * @var string - */ -define('FirePHP_DUMP', 'DUMP'); - -/** - * Displays a stack trace in firebug console - * - * @var string - */ -define('FirePHP_TRACE', 'TRACE'); - -/** - * Displays a table in firebug console - * - * @var string - */ -define('FirePHP_TABLE', 'TABLE'); - -/** - * Starts a group in firebug console - * - * @var string - */ -define('FirePHP_GROUP_START', 'GROUP_START'); - -/** - * Ends a group in firebug console - * - * @var string - */ -define('FirePHP_GROUP_END', 'GROUP_END'); - -/** - * Sends the given data to the FirePHP Firefox Extension. - * The data can be displayed in the Firebug Console or in the - * "Server" request tab. - * - * For more information see: http://www.firephp.org/ - * - * @copyright Copyright (C) 2007-2009 Christoph Dorn - * @author Christoph Dorn - * @author Michael Day - * @license http://www.opensource.org/licenses/bsd-license.php - * @package FirePHPCore - */ -class FirePHP { - /** - * Wildfire protocol message index - * - * @var int - */ - var $messageIndex = 1; - - /** - * Options for the library - * - * @var array - */ - var $options = array('maxObjectDepth' => 5, - 'maxArrayDepth' => 5, - 'useNativeJsonEncode' => true, - 'includeLineNumbers' => true); - - /** - * Filters used to exclude object members when encoding - * - * @var array - */ - var $objectFilters = array(); - - /** - * A stack of objects used to detect recursion during object encoding - * - * @var object - */ - var $objectStack = array(); - - /** - * Flag to enable/disable logging - * - * @var boolean - */ - var $enabled = true; - - /** - * The object constructor - */ - function FirePHP() { - } - - - /** - * When the object gets serialized only include specific object members. - * - * @return array - */ - function __sleep() { - return array('options','objectFilters','enabled'); - } - - /** - * Gets singleton instance of FirePHP - * - * @param boolean $AutoCreate - * @return FirePHP - */ - function &getInstance($AutoCreate=false) { - global $FirePHP_Instance; - - if($AutoCreate===true && !$FirePHP_Instance) { - $FirePHP_Instance = new FirePHP(); - } - - return $FirePHP_Instance; - } - - /** - * Enable and disable logging to Firebug - * - * @param boolean $Enabled TRUE to enable, FALSE to disable - * @return void - */ - function setEnabled($Enabled) { - $this->enabled = $Enabled; - } - - /** - * Check if logging is enabled - * - * @return boolean TRUE if enabled - */ - function getEnabled() { - return $this->enabled; - } - - /** - * Specify a filter to be used when encoding an object - * - * Filters are used to exclude object members. - * - * @param string $Class The class name of the object - * @param array $Filter An array of members to exclude - * @return void - */ - function setObjectFilter($Class, $Filter) { - $this->objectFilters[strtolower($Class)] = $Filter; - } - - /** - * Set some options for the library - * - * Options: - * - maxObjectDepth: The maximum depth to traverse objects (default: 5) - * - maxArrayDepth: The maximum depth to traverse arrays (default: 5) - * - useNativeJsonEncode: If true will use json_encode() (default: true) - * - includeLineNumbers: If true will include line numbers and filenames (default: true) - * - * @param array $Options The options to be set - * @return void - */ - function setOptions($Options) { - $this->options = array_merge($this->options,$Options); - } - - /** - * Get options from the library - * - * @return array The currently set options - */ - function getOptions() { - return $this->options; - } - - /** - * Register FirePHP as your error handler - * - * Will use FirePHP to log each php error. - * - * @return mixed Returns a string containing the previously defined error handler (if any) - */ - function registerErrorHandler() - { - //NOTE: The following errors will not be caught by this error handler: - // E_ERROR, E_PARSE, E_CORE_ERROR, - // E_CORE_WARNING, E_COMPILE_ERROR, - // E_COMPILE_WARNING, E_STRICT - - return set_error_handler(array($this,'errorHandler')); - } - - /** - * FirePHP's error handler - * - * Logs each php error that will occur. - * - * @param int $errno - * @param string $errstr - * @param string $errfile - * @param int $errline - * @param array $errcontext - */ - function errorHandler($errno, $errstr, $errfile, $errline, $errcontext) - { - global $FirePHP_Instance; - // Don't log error if error reporting is switched off - if (error_reporting() == 0) { - return; - } - // Only log error for errors we are asking for - if (error_reporting() & $errno) { - $FirePHP_Instance->group($errstr); - $FirePHP_Instance->error("{$errfile}, line $errline"); - $FirePHP_Instance->groupEnd(); - } - } - - /** - * Register FirePHP driver as your assert callback - * - * @return mixed Returns the original setting - */ - function registerAssertionHandler() - { - return assert_options(ASSERT_CALLBACK, array($this, 'assertionHandler')); - } - - /** - * FirePHP's assertion handler - * - * Logs all assertions to your firebug console and then stops the script. - * - * @param string $file File source of assertion - * @param int $line Line source of assertion - * @param mixed $code Assertion code - */ - function assertionHandler($file, $line, $code) - { - $this->fb($code, 'Assertion Failed', FirePHP_ERROR, array('File'=>$file,'Line'=>$line)); - } - - /** - * Set custom processor url for FirePHP - * - * @param string $URL - */ - function setProcessorUrl($URL) - { - $this->setHeader('X-FirePHP-ProcessorURL', $URL); - } - - /** - * Set custom renderer url for FirePHP - * - * @param string $URL - */ - function setRendererUrl($URL) - { - $this->setHeader('X-FirePHP-RendererURL', $URL); - } - - /** - * Start a group for following messages. - * - * Options: - * Collapsed: [true|false] - * Color: [#RRGGBB|ColorName] - * - * @param string $Name - * @param array $Options OPTIONAL Instructions on how to log the group - * @return true - * @throws Exception - */ - function group($Name, $Options=null) { - - if(!$Name) { - trigger_error('You must specify a label for the group!'); - } - - if($Options) { - if(!is_array($Options)) { - trigger_error('Options must be defined as an array!'); - } - if(array_key_exists('Collapsed', $Options)) { - $Options['Collapsed'] = ($Options['Collapsed'])?'true':'false'; - } - } - - return $this->fb(null, $Name, FirePHP_GROUP_START, $Options); - } - - /** - * Ends a group you have started before - * - * @return true - * @throws Exception - */ - function groupEnd() { - return $this->fb(null, null, FirePHP_GROUP_END); - } - - /** - * Log object with label to firebug console - * - * @see FirePHP::LOG - * @param mixes $Object - * @param string $Label - * @return true - * @throws Exception - */ - function log($Object, $Label=null) { - return $this->fb($Object, $Label, FirePHP_LOG); - } - - /** - * Log object with label to firebug console - * - * @see FirePHP::INFO - * @param mixes $Object - * @param string $Label - * @return true - * @throws Exception - */ - function info($Object, $Label=null) { - return $this->fb($Object, $Label, FirePHP_INFO); - } - - /** - * Log object with label to firebug console - * - * @see FirePHP::WARN - * @param mixes $Object - * @param string $Label - * @return true - * @throws Exception - */ - function warn($Object, $Label=null) { - return $this->fb($Object, $Label, FirePHP_WARN); - } - - /** - * Log object with label to firebug console - * - * @see FirePHP::ERROR - * @param mixes $Object - * @param string $Label - * @return true - * @throws Exception - */ - function error($Object, $Label=null) { - return $this->fb($Object, $Label, FirePHP_ERROR); - } - - /** - * Dumps key and variable to firebug server panel - * - * @see FirePHP::DUMP - * @param string $Key - * @param mixed $Variable - * @return true - * @throws Exception - */ - function dump($Key, $Variable) { - return $this->fb($Variable, $Key, FirePHP_DUMP); - } - - /** - * Log a trace in the firebug console - * - * @see FirePHP::TRACE - * @param string $Label - * @return true - * @throws Exception - */ - function trace($Label) { - return $this->fb($Label, FirePHP_TRACE); - } - - /** - * Log a table in the firebug console - * - * @see FirePHP::TABLE - * @param string $Label - * @param string $Table - * @return true - * @throws Exception - */ - function table($Label, $Table) { - return $this->fb($Table, $Label, FirePHP_TABLE); - } - - /** - * Check if FirePHP is installed on client - * - * @return boolean - */ - function detectClientExtension() { - // Check if FirePHP is installed on client via User-Agent header - if(@preg_match_all('/\sFirePHP\/([\.\d]*)\s?/si',$this->getUserAgent(),$m) && - version_compare($m[1][0],'0.0.6','>=')) { - return true; - } else - // Check if FirePHP is installed on client via X-FirePHP-Version header - if(@preg_match_all('/^([\.\d]*)$/si',$this->getRequestHeader("X-FirePHP-Version"),$m) && - version_compare($m[1][0],'0.0.6','>=')) { - return true; - } - return false; - } - - /** - * Log varible to Firebug - * - * @see http://www.firephp.org/Wiki/Reference/Fb - * @param mixed $Object The variable to be logged - * @return true Return TRUE if message was added to headers, FALSE otherwise - * @throws Exception - */ - function fb($Object) { - - if(!$this->enabled) { - return false; - } - - if (headers_sent($filename, $linenum)) { - trigger_error('Headers already sent in '.$filename.' on line '.$linenum.'. Cannot send log data to FirePHP. You must have Output Buffering enabled via ob_start() or output_buffering ini directive.'); - } - - $Type = null; - $Label = null; - $Options = array(); - - if(func_num_args()==1) { - } else - if(func_num_args()==2) { - switch(func_get_arg(1)) { - case FirePHP_LOG: - case FirePHP_INFO: - case FirePHP_WARN: - case FirePHP_ERROR: - case FirePHP_DUMP: - case FirePHP_TRACE: - case FirePHP_TABLE: - case FirePHP_GROUP_START: - case FirePHP_GROUP_END: - $Type = func_get_arg(1); - break; - default: - $Label = func_get_arg(1); - break; - } - } else - if(func_num_args()==3) { - $Type = func_get_arg(2); - $Label = func_get_arg(1); - } else - if(func_num_args()==4) { - $Type = func_get_arg(2); - $Label = func_get_arg(1); - $Options = func_get_arg(3); - } else { - trigger_error('Wrong number of arguments to fb() function!'); - } - - - if(!$this->detectClientExtension()) { - return false; - } - - $meta = array(); - $skipFinalObjectEncode = false; - - if($Type==FirePHP_TRACE) { - - $trace = debug_backtrace(); - if(!$trace) return false; - for( $i=0 ; $i_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php' - || substr($this->_standardizePath($trace[$i]['file']),-29,29)=='FirePHPCore/FirePHP.class.php')) { - /* Skip - FB::trace(), FB::send(), $firephp->trace(), $firephp->fb() */ - } else - if(isset($trace[$i]['class']) - && isset($trace[$i+1]['file']) - && $trace[$i]['class']=='FirePHP' - && substr($this->_standardizePath($trace[$i+1]['file']),-18,18)=='FirePHPCore/fb.php') { - /* Skip fb() */ - } else - if($trace[$i]['function']=='fb' - || $trace[$i]['function']=='trace' - || $trace[$i]['function']=='send') { - $Object = array('Class'=>isset($trace[$i]['class'])?$trace[$i]['class']:'', - 'Type'=>isset($trace[$i]['type'])?$trace[$i]['type']:'', - 'Function'=>isset($trace[$i]['function'])?$trace[$i]['function']:'', - 'Message'=>$trace[$i]['args'][0], - 'File'=>isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):'', - 'Line'=>isset($trace[$i]['line'])?$trace[$i]['line']:'', - 'Args'=>isset($trace[$i]['args'])?$this->encodeObject($trace[$i]['args']):'', - 'Trace'=>$this->_escapeTrace(array_splice($trace,$i+1))); - - $skipFinalObjectEncode = true; - $meta['file'] = isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):''; - $meta['line'] = isset($trace[$i]['line'])?$trace[$i]['line']:''; - break; - } - } - - } else - if($Type==FirePHP_TABLE) { - - if(isset($Object[0]) && is_string($Object[0])) { - $Object[1] = $this->encodeTable($Object[1]); - } else { - $Object = $this->encodeTable($Object); - } - - $skipFinalObjectEncode = true; - - } else - if($Type==FirePHP_GROUP_START) { - - if(!$Label) { - trigger_error('You must specify a label for the group!'); - } - } else { - if($Type===null) { - $Type = FirePHP_LOG; - } - } - - if($this->options['includeLineNumbers']) { - if(!isset($meta['file']) || !isset($meta['line'])) { - - $trace = debug_backtrace(); - for( $i=0 ; $trace && $i_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php' - || substr($this->_standardizePath($trace[$i]['file']),-29,29)=='FirePHPCore/FirePHP.class.php')) { - /* Skip - FB::trace(), FB::send(), $firephp->trace(), $firephp->fb() */ - } else - if(isset($trace[$i]['class']) - && isset($trace[$i+1]['file']) - && $trace[$i]['class']=='FirePHP' - && substr($this->_standardizePath($trace[$i+1]['file']),-18,18)=='FirePHPCore/fb.php') { - /* Skip fb() */ - } else - if(isset($trace[$i]['file']) - && substr($this->_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php') { - /* Skip FB::fb() */ - } else { - $meta['file'] = isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):''; - $meta['line'] = isset($trace[$i]['line'])?$trace[$i]['line']:''; - break; - } - } - - } - } else { - unset($meta['file']); - unset($meta['line']); - } - - $this->setHeader('X-Wf-Protocol-1','http://meta.wildfirehq.org/Protocol/JsonStream/0.2'); - $this->setHeader('X-Wf-1-Plugin-1','http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/'.FirePHP_VERSION); - - $structure_index = 1; - if($Type==FirePHP_DUMP) { - $structure_index = 2; - $this->setHeader('X-Wf-1-Structure-2','http://meta.firephp.org/Wildfire/Structure/FirePHP/Dump/0.1'); - } else { - $this->setHeader('X-Wf-1-Structure-1','http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1'); - } - - if($Type==FirePHP_DUMP) { - $msg = '{"'.$Label.'":'.$this->jsonEncode($Object, $skipFinalObjectEncode).'}'; - } else { - $msg_meta = $Options; - $msg_meta['Type'] = $Type; - if($Label!==null) { - $msg_meta['Label'] = $Label; - } - if(isset($meta['file']) && !isset($msg_meta['File'])) { - $msg_meta['File'] = $meta['file']; - } - if(isset($meta['line']) && !isset($msg_meta['Line'])) { - $msg_meta['Line'] = $meta['line']; - } - $msg = '['.$this->jsonEncode($msg_meta).','.$this->jsonEncode($Object, $skipFinalObjectEncode).']'; - } - - $parts = explode("\n",chunk_split($msg, 5000, "\n")); - - for( $i=0 ; $i2) { - // Message needs to be split into multiple parts - $this->setHeader('X-Wf-1-'.$structure_index.'-'.'1-'.$this->messageIndex, - (($i==0)?strlen($msg):'') - . '|' . $part . '|' - . (($isetHeader('X-Wf-1-'.$structure_index.'-'.'1-'.$this->messageIndex, - strlen($part) . '|' . $part . '|'); - } - - $this->messageIndex++; - - if ($this->messageIndex > 99999) { - trigger_error('Maximum number (99,999) of messages reached!'); - } - } - } - - $this->setHeader('X-Wf-1-Index',$this->messageIndex-1); - - return true; - } - - - /** - * Standardizes path for windows systems. - * - * @param string $Path - * @return string - */ - function _standardizePath($Path) { - return preg_replace('/\\\\+/','/',$Path); - } - - /** - * Escape trace path for windows systems - * - * @param array $Trace - * @return array - */ - function _escapeTrace($Trace) { - if(!$Trace) return $Trace; - for( $i=0 ; $i_escapeTraceFile($Trace[$i]['file']); - } - if(isset($Trace[$i]['args'])) { - $Trace[$i]['args'] = $this->encodeObject($Trace[$i]['args']); - } - } - return $Trace; - } - - /** - * Escape file information of trace for windows systems - * - * @param string $File - * @return string - */ - function _escapeTraceFile($File) { - /* Check if we have a windows filepath */ - if(strpos($File,'\\')) { - /* First strip down to single \ */ - - $file = preg_replace('/\\\\+/','\\',$File); - - return $file; - } - return $File; - } - - /** - * Send header - * - * @param string $Name - * @param string_type $Value - */ - function setHeader($Name, $Value) { - return header($Name.': '.$Value); - } - - /** - * Get user agent - * - * @return string|false - */ - function getUserAgent() { - if(!isset($_SERVER['HTTP_USER_AGENT'])) return false; - return $_SERVER['HTTP_USER_AGENT']; - } - - /** - * Get all request headers - * - * @return array - */ - function getAllRequestHeaders() { - $headers = array(); - if(function_exists('getallheaders')) { - foreach( getallheaders() as $name => $value ) { - $headers[strtolower($name)] = $value; - } - } else { - foreach($_SERVER as $name => $value) { - if(substr($name, 0, 5) == 'HTTP_') { - $headers[strtolower(str_replace(' ', '-', str_replace('_', ' ', substr($name, 5))))] = $value; - } - } - } - return $headers; - } - - /** - * Get a request header - * - * @return string|false - */ - function getRequestHeader($Name) - { - $headers = $this->getAllRequestHeaders(); - if (isset($headers[strtolower($Name)])) { - return $headers[strtolower($Name)]; - } - return false; - } - - /** - * Encode an object into a JSON string - * - * Uses PHP's jeson_encode() if available - * - * @param object $Object The object to be encoded - * @return string The JSON string - */ - function jsonEncode($Object, $skipObjectEncode=false) - { - if(!$skipObjectEncode) { - $Object = $this->encodeObject($Object); - } - - if(function_exists('json_encode') - && $this->options['useNativeJsonEncode']!=false) { - - return json_encode($Object); - } else { - return $this->json_encode($Object); - } - } - - /** - * Encodes a table by encoding each row and column with encodeObject() - * - * @param array $Table The table to be encoded - * @return array - */ - function encodeTable($Table) { - - if(!$Table) return $Table; - - $new_table = array(); - foreach($Table as $row) { - - if(is_array($row)) { - $new_row = array(); - - foreach($row as $item) { - $new_row[] = $this->encodeObject($item); - } - - $new_table[] = $new_row; - } - } - - return $new_table; - } - - /** - * Encodes an object - * - * @param Object $Object The object to be encoded - * @param int $Depth The current traversal depth - * @return array All members of the object - */ - function encodeObject($Object, $ObjectDepth = 1, $ArrayDepth = 1) - { - $return = array(); - - if (is_resource($Object)) { - - return '** '.(string)$Object.' **'; - - } else - if (is_object($Object)) { - - if ($ObjectDepth > $this->options['maxObjectDepth']) { - return '** Max Object Depth ('.$this->options['maxObjectDepth'].') **'; - } - - foreach ($this->objectStack as $refVal) { - if ($refVal === $Object) { - return '** Recursion ('.get_class($Object).') **'; - } - } - array_push($this->objectStack, $Object); - - $return['__className'] = $class = get_class($Object); - $class_lower = strtolower($class); - - $members = (array)$Object; - - // Include all members that are not defined in the class - // but exist in the object - foreach( $members as $raw_name => $value ) { - - $name = $raw_name; - - if ($name{0} == "\0") { - $parts = explode("\0", $name); - $name = $parts[2]; - } - - if(!isset($properties[$name])) { - $name = 'undeclared:'.$name; - - if(!(isset($this->objectFilters[$class_lower]) - && is_array($this->objectFilters[$class_lower]) - && in_array($raw_name,$this->objectFilters[$class_lower]))) { - - $return[$name] = $this->encodeObject($value, $ObjectDepth + 1, 1); - } else { - $return[$name] = '** Excluded by Filter **'; - } - } - } - - array_pop($this->objectStack); - - } elseif (is_array($Object)) { - - if ($ArrayDepth > $this->options['maxArrayDepth']) { - return '** Max Array Depth ('.$this->options['maxArrayDepth'].') **'; - } - - foreach ($Object as $key => $val) { - - // Encoding the $GLOBALS PHP array causes an infinite loop - // if the recursion is not reset here as it contains - // a reference to itself. This is the only way I have come up - // with to stop infinite recursion in this case. - if($key=='GLOBALS' - && is_array($val) - && array_key_exists('GLOBALS',$val)) { - $val['GLOBALS'] = '** Recursion (GLOBALS) **'; - } - - $return[$key] = $this->encodeObject($val, 1, $ArrayDepth + 1); - } - } else { - if($this->is_utf8($Object)) { - return $Object; - } else { - return utf8_encode($Object); - } - } - return $return; - - } - - /** - * Returns true if $string is valid UTF-8 and false otherwise. - * - * @param mixed $str String to be tested - * @return boolean - */ - function is_utf8($str) { - $c=0; $b=0; - $bits=0; - $len=strlen($str); - for($i=0; $i<$len; $i++){ - $c=ord($str[$i]); - if($c > 128){ - if(($c >= 254)) return false; - elseif($c >= 252) $bits=6; - elseif($c >= 248) $bits=5; - elseif($c >= 240) $bits=4; - elseif($c >= 224) $bits=3; - elseif($c >= 192) $bits=2; - else return false; - if(($i+$bits) > $len) return false; - while($bits > 1){ - $i++; - $b=ord($str[$i]); - if($b < 128 || $b > 191) return false; - $bits--; - } - } - } - return true; - } - - /** - * Converts to and from JSON format. - * - * JSON (JavaScript Object Notation) is a lightweight data-interchange - * format. It is easy for humans to read and write. It is easy for machines - * to parse and generate. It is based on a subset of the JavaScript - * Programming Language, Standard ECMA-262 3rd Edition - December 1999. - * This feature can also be found in Python. JSON is a text format that is - * completely language independent but uses conventions that are familiar - * to programmers of the C-family of languages, including C, C++, C#, Java, - * JavaScript, Perl, TCL, and many others. These properties make JSON an - * ideal data-interchange language. - * - * This package provides a simple encoder and decoder for JSON notation. It - * is intended for use with client-side Javascript applications that make - * use of HTTPRequest to perform server communication functions - data can - * be encoded into JSON notation for use in a client-side javascript, or - * decoded from incoming Javascript requests. JSON format is native to - * Javascript, and can be directly eval()'ed with no further parsing - * overhead - * - * All strings should be in ASCII or UTF-8 format! - * - * LICENSE: Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: Redistributions of source code must retain the - * above copyright notice, this list of conditions and the following - * disclaimer. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * @category - * @package Services_JSON - * @author Michal Migurski - * @author Matt Knapp - * @author Brett Stimmerman - * @author Christoph Dorn - * @copyright 2005 Michal Migurski - * @version CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $ - * @license http://www.opensource.org/licenses/bsd-license.php - * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 - */ - - - /** - * Keep a list of objects as we descend into the array so we can detect recursion. - */ - var $json_objectStack = array(); - - - /** - * convert a string from one UTF-8 char to one UTF-16 char - * - * Normally should be handled by mb_convert_encoding, but - * provides a slower PHP-only method for installations - * that lack the multibye string extension. - * - * @param string $utf8 UTF-8 character - * @return string UTF-16 character - * @access private - */ - function json_utf82utf16($utf8) - { - // oh please oh please oh please oh please oh please - if(function_exists('mb_convert_encoding')) { - return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8'); - } - - switch(strlen($utf8)) { - case 1: - // this case should never be reached, because we are in ASCII range - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return $utf8; - - case 2: - // return a UTF-16 character from a 2-byte UTF-8 char - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return chr(0x07 & (ord($utf8{0}) >> 2)) - . chr((0xC0 & (ord($utf8{0}) << 6)) - | (0x3F & ord($utf8{1}))); - - case 3: - // return a UTF-16 character from a 3-byte UTF-8 char - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return chr((0xF0 & (ord($utf8{0}) << 4)) - | (0x0F & (ord($utf8{1}) >> 2))) - . chr((0xC0 & (ord($utf8{1}) << 6)) - | (0x7F & ord($utf8{2}))); - } - - // ignoring UTF-32 for now, sorry - return ''; - } - - /** - * encodes an arbitrary variable into JSON format - * - * @param mixed $var any number, boolean, string, array, or object to be encoded. - * see argument 1 to Services_JSON() above for array-parsing behavior. - * if var is a strng, note that encode() always expects it - * to be in ASCII or UTF-8 format! - * - * @return mixed JSON string representation of input var or an error if a problem occurs - * @access public - */ - function json_encode($var) - { - - if(is_object($var)) { - if(in_array($var,$this->json_objectStack)) { - return '"** Recursion **"'; - } - } - - switch (gettype($var)) { - case 'boolean': - return $var ? 'true' : 'false'; - - case 'NULL': - return 'null'; - - case 'integer': - return (int) $var; - - case 'double': - case 'float': - return (float) $var; - - case 'string': - // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT - $ascii = ''; - $strlen_var = strlen($var); - - /* - * Iterate over every character in the string, - * escaping with a slash or encoding to UTF-8 where necessary - */ - for ($c = 0; $c < $strlen_var; ++$c) { - - $ord_var_c = ord($var{$c}); - - switch (true) { - case $ord_var_c == 0x08: - $ascii .= '\b'; - break; - case $ord_var_c == 0x09: - $ascii .= '\t'; - break; - case $ord_var_c == 0x0A: - $ascii .= '\n'; - break; - case $ord_var_c == 0x0C: - $ascii .= '\f'; - break; - case $ord_var_c == 0x0D: - $ascii .= '\r'; - break; - - case $ord_var_c == 0x22: - case $ord_var_c == 0x2F: - case $ord_var_c == 0x5C: - // double quote, slash, slosh - $ascii .= '\\'.$var{$c}; - break; - - case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): - // characters U-00000000 - U-0000007F (same as ASCII) - $ascii .= $var{$c}; - break; - - case (($ord_var_c & 0xE0) == 0xC0): - // characters U-00000080 - U-000007FF, mask 110XXXXX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, ord($var{$c + 1})); - $c += 1; - $utf16 = $this->json_utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - - case (($ord_var_c & 0xF0) == 0xE0): - // characters U-00000800 - U-0000FFFF, mask 1110XXXX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, - ord($var{$c + 1}), - ord($var{$c + 2})); - $c += 2; - $utf16 = $this->json_utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - - case (($ord_var_c & 0xF8) == 0xF0): - // characters U-00010000 - U-001FFFFF, mask 11110XXX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, - ord($var{$c + 1}), - ord($var{$c + 2}), - ord($var{$c + 3})); - $c += 3; - $utf16 = $this->json_utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - - case (($ord_var_c & 0xFC) == 0xF8): - // characters U-00200000 - U-03FFFFFF, mask 111110XX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, - ord($var{$c + 1}), - ord($var{$c + 2}), - ord($var{$c + 3}), - ord($var{$c + 4})); - $c += 4; - $utf16 = $this->json_utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - - case (($ord_var_c & 0xFE) == 0xFC): - // characters U-04000000 - U-7FFFFFFF, mask 1111110X - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, - ord($var{$c + 1}), - ord($var{$c + 2}), - ord($var{$c + 3}), - ord($var{$c + 4}), - ord($var{$c + 5})); - $c += 5; - $utf16 = $this->json_utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - } - } - - return '"'.$ascii.'"'; - - case 'array': - /* - * As per JSON spec if any array key is not an integer - * we must treat the the whole array as an object. We - * also try to catch a sparsely populated associative - * array with numeric keys here because some JS engines - * will create an array with empty indexes up to - * max_index which can cause memory issues and because - * the keys, which may be relevant, will be remapped - * otherwise. - * - * As per the ECMA and JSON specification an object may - * have any string as a property. Unfortunately due to - * a hole in the ECMA specification if the key is a - * ECMA reserved word or starts with a digit the - * parameter is only accessible using ECMAScript's - * bracket notation. - */ - - // treat as a JSON object - if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { - - $this->json_objectStack[] = $var; - - $properties = array_map(array($this, 'json_name_value'), - array_keys($var), - array_values($var)); - - array_pop($this->json_objectStack); - - return '{' . join(',', $properties) . '}'; - } - - $this->json_objectStack[] = $var; - - // treat it like a regular array - $elements = array_map(array($this, 'json_encode'), $var); - - array_pop($this->json_objectStack); - - return '[' . join(',', $elements) . ']'; - - case 'object': - $vars = FirePHP::encodeObject($var); - - $this->json_objectStack[] = $var; - - $properties = array_map(array($this, 'json_name_value'), - array_keys($vars), - array_values($vars)); - - array_pop($this->json_objectStack); - - return '{' . join(',', $properties) . '}'; - - default: - return null; - } - } - - /** - * array-walking function for use in generating JSON-formatted name-value pairs - * - * @param string $name name of key to use - * @param mixed $value reference to an array element to be encoded - * - * @return string JSON-formatted name-value pair, like '"name":value' - * @access private - */ - function json_name_value($name, $value) - { - // Encoding the $GLOBALS PHP array causes an infinite loop - // if the recursion is not reset here as it contains - // a reference to itself. This is the only way I have come up - // with to stop infinite recursion in this case. - if($name=='GLOBALS' - && is_array($value) - && array_key_exists('GLOBALS',$value)) { - $value['GLOBALS'] = '** Recursion **'; - } - - $encoded_value = $this->json_encode($value); - - return $this->json_encode(strval($name)) . ':' . $encoded_value; - } -} - diff --git a/engine/external/pear/FirePHPCore/LICENSE b/engine/external/pear/FirePHPCore/LICENSE deleted file mode 100644 index 3e390f9d..00000000 --- a/engine/external/pear/FirePHPCore/LICENSE +++ /dev/null @@ -1,29 +0,0 @@ -Software License Agreement (New BSD License) - -Copyright (c) 2006-2009, Christoph Dorn -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - * Neither the name of Christoph Dorn nor the names of its - contributors may be used to endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/engine/external/pear/FirePHPCore/fb.php b/engine/external/pear/FirePHPCore/fb.php deleted file mode 100644 index 9ed9c423..00000000 --- a/engine/external/pear/FirePHPCore/fb.php +++ /dev/null @@ -1,276 +0,0 @@ - - * @license http://www.opensource.org/licenses/bsd-license.php - * @package FirePHPCore - */ - -if(!class_exists('FirePHP')) { - require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'FirePHP.class.php'; -} - -/** - * Sends the given data to the FirePHP Firefox Extension. - * The data can be displayed in the Firebug Console or in the - * "Server" request tab. - * - * @see http://www.firephp.org/Wiki/Reference/Fb - * @param mixed $Object - * @return true - * @throws Exception - */ -function fb() -{ - $instance = FirePHP::getInstance(true); - - $args = func_get_args(); - return call_user_func_array(array($instance,'fb'),$args); -} - - -class FB -{ - /** - * Enable and disable logging to Firebug - * - * @see FirePHP->setEnabled() - * @param boolean $Enabled TRUE to enable, FALSE to disable - * @return void - */ - public static function setEnabled($Enabled) - { - $instance = FirePHP::getInstance(true); - $instance->setEnabled($Enabled); - } - - /** - * Check if logging is enabled - * - * @see FirePHP->getEnabled() - * @return boolean TRUE if enabled - */ - public static function getEnabled() - { - $instance = FirePHP::getInstance(true); - return $instance->getEnabled(); - } - - /** - * Specify a filter to be used when encoding an object - * - * Filters are used to exclude object members. - * - * @see FirePHP->setObjectFilter() - * @param string $Class The class name of the object - * @param array $Filter An array or members to exclude - * @return void - */ - public static function setObjectFilter($Class, $Filter) - { - $instance = FirePHP::getInstance(true); - $instance->setObjectFilter($Class, $Filter); - } - - /** - * Set some options for the library - * - * @see FirePHP->setOptions() - * @param array $Options The options to be set - * @return void - */ - public static function setOptions($Options) - { - $instance = FirePHP::getInstance(true); - $instance->setOptions($Options); - } - - /** - * Get options for the library - * - * @see FirePHP->getOptions() - * @return array The options - */ - public static function getOptions() - { - $instance = FirePHP::getInstance(true); - return $instance->getOptions(); - } - - /** - * Log object to firebug - * - * @see http://www.firephp.org/Wiki/Reference/Fb - * @param mixed $Object - * @return true - * @throws Exception - */ - public static function send() - { - $instance = FirePHP::getInstance(true); - $args = func_get_args(); - return call_user_func_array(array($instance,'fb'),$args); - } - - /** - * Start a group for following messages - * - * Options: - * Collapsed: [true|false] - * Color: [#RRGGBB|ColorName] - * - * @param string $Name - * @param array $Options OPTIONAL Instructions on how to log the group - * @return true - */ - public static function group($Name, $Options=null) - { - $instance = FirePHP::getInstance(true); - return $instance->group($Name, $Options); - } - - /** - * Ends a group you have started before - * - * @return true - * @throws Exception - */ - public static function groupEnd() - { - return self::send(null, null, FirePHP::GROUP_END); - } - - /** - * Log object with label to firebug console - * - * @see FirePHP::LOG - * @param mixes $Object - * @param string $Label - * @return true - * @throws Exception - */ - public static function log($Object, $Label=null) - { - return self::send($Object, $Label, FirePHP::LOG); - } - - /** - * Log object with label to firebug console - * - * @see FirePHP::INFO - * @param mixes $Object - * @param string $Label - * @return true - * @throws Exception - */ - public static function info($Object, $Label=null) - { - return self::send($Object, $Label, FirePHP::INFO); - } - - /** - * Log object with label to firebug console - * - * @see FirePHP::WARN - * @param mixes $Object - * @param string $Label - * @return true - * @throws Exception - */ - public static function warn($Object, $Label=null) - { - return self::send($Object, $Label, FirePHP::WARN); - } - - /** - * Log object with label to firebug console - * - * @see FirePHP::ERROR - * @param mixes $Object - * @param string $Label - * @return true - * @throws Exception - */ - public static function error($Object, $Label=null) - { - return self::send($Object, $Label, FirePHP::ERROR); - } - - /** - * Dumps key and variable to firebug server panel - * - * @see FirePHP::DUMP - * @param string $Key - * @param mixed $Variable - * @return true - * @throws Exception - */ - public static function dump($Key, $Variable) - { - return self::send($Variable, $Key, FirePHP::DUMP); - } - - /** - * Log a trace in the firebug console - * - * @see FirePHP::TRACE - * @param string $Label - * @return true - * @throws Exception - */ - public static function trace($Label) - { - return self::send($Label, FirePHP::TRACE); - } - - /** - * Log a table in the firebug console - * - * @see FirePHP::TABLE - * @param string $Label - * @param string $Table - * @return true - * @throws Exception - */ - public static function table($Label, $Table) - { - return self::send($Table, $Label, FirePHP::TABLE); - } - -} diff --git a/engine/external/pear/FirePHPCore/fb.php4 b/engine/external/pear/FirePHPCore/fb.php4 deleted file mode 100644 index b0688cfe..00000000 --- a/engine/external/pear/FirePHPCore/fb.php4 +++ /dev/null @@ -1,251 +0,0 @@ - - * @author Michael Day - * @license http://www.opensource.org/licenses/bsd-license.php - * @package FirePHPCore - */ - -require_once dirname(__FILE__).'/FirePHP.class.php4'; - -/** - * Sends the given data to the FirePHP Firefox Extension. - * The data can be displayed in the Firebug Console or in the - * "Server" request tab. - * - * @see http://www.firephp.org/Wiki/Reference/Fb - * @param mixed $Object - * @return true - * @throws Exception - */ -function fb() -{ - $instance =& FirePHP::getInstance(true); - - $args = func_get_args(); - return call_user_func_array(array(&$instance,'fb'),$args); -} - - -class FB -{ - /** - * Enable and disable logging to Firebug - * - * @see FirePHP->setEnabled() - * @param boolean $Enabled TRUE to enable, FALSE to disable - * @return void - */ - function setEnabled($Enabled) { - $instance =& FirePHP::getInstance(true); - $instance->setEnabled($Enabled); - } - - /** - * Check if logging is enabled - * - * @see FirePHP->getEnabled() - * @return boolean TRUE if enabled - */ - function getEnabled() { - $instance =& FirePHP::getInstance(true); - return $instance->getEnabled(); - } - - /** - * Specify a filter to be used when encoding an object - * - * Filters are used to exclude object members. - * - * @see FirePHP->setObjectFilter() - * @param string $Class The class name of the object - * @param array $Filter An array or members to exclude - * @return void - */ - function setObjectFilter($Class, $Filter) { - $instance =& FirePHP::getInstance(true); - $instance->setObjectFilter($Class, $Filter); - } - - /** - * Set some options for the library - * - * @see FirePHP->setOptions() - * @param array $Options The options to be set - * @return void - */ - function setOptions($Options) { - $instance =& FirePHP::getInstance(true); - $instance->setOptions($Options); - } - - /** - * Get options for the library - * - * @see FirePHP->getOptions() - * @return array The options - */ - function getOptions() { - $instance =& FirePHP::getInstance(true); - return $instance->getOptions(); - } - - /** - * Log object to firebug - * - * @see http://www.firephp.org/Wiki/Reference/Fb - * @param mixed $Object - * @return true - */ - function send() - { - $instance =& FirePHP::getInstance(true); - $args = func_get_args(); - return call_user_func_array(array(&$instance,'fb'),$args); - } - - /** - * Start a group for following messages - * - * Options: - * Collapsed: [true|false] - * Color: [#RRGGBB|ColorName] - * - * @param string $Name - * @param array $Options OPTIONAL Instructions on how to log the group - * @return true - */ - function group($Name, $Options=null) { - $instance =& FirePHP::getInstance(true); - return $instance->group($Name, $Options); - } - - /** - * Ends a group you have started before - * - * @return true - */ - function groupEnd() { - return FB::send(null, null, FirePHP_GROUP_END); - } - - /** - * Log object with label to firebug console - * - * @see FirePHP::LOG - * @param mixes $Object - * @param string $Label - * @return true - */ - function log($Object, $Label=null) { - return FB::send($Object, $Label, FirePHP_LOG); - } - - /** - * Log object with label to firebug console - * - * @see FirePHP::INFO - * @param mixes $Object - * @param string $Label - * @return true - */ - function info($Object, $Label=null) { - return FB::send($Object, $Label, FirePHP_INFO); - } - - /** - * Log object with label to firebug console - * - * @see FirePHP::WARN - * @param mixes $Object - * @param string $Label - * @return true - */ - function warn($Object, $Label=null) { - return FB::send($Object, $Label, FirePHP_WARN); - } - - /** - * Log object with label to firebug console - * - * @see FirePHP::ERROR - * @param mixes $Object - * @param string $Label - * @return true - */ - function error($Object, $Label=null) { - return FB::send($Object, $Label, FirePHP_ERROR); - } - - /** - * Dumps key and variable to firebug server panel - * - * @see FirePHP::DUMP - * @param string $Key - * @param mixed $Variable - * @return true - */ - function dump($Key, $Variable) { - return FB::send($Variable, $Key, FirePHP_DUMP); - } - - /** - * Log a trace in the firebug console - * - * @see FirePHP::TRACE - * @param string $Label - * @return true - */ - function trace($Label) { - return FB::send($Label, FirePHP_TRACE); - } - - /** - * Log a table in the firebug console - * - * @see FirePHP::TABLE - * @param string $Label - * @param string $Table - * @return true - */ - function table($Label, $Table) { - return FB::send($Table, $Label, FirePHP_TABLE); - } -} diff --git a/engine/external/pear/HTML/Select.php b/engine/external/pear/HTML/Select.php index 47f4bd88..f5cc7fbb 100644 --- a/engine/external/pear/HTML/Select.php +++ b/engine/external/pear/HTML/Select.php @@ -13,7 +13,7 @@ * @link http://pear.php.net/package/HTML_Select */ -require_once __DIR__ . '/../../../include/vendor/autoload.php'; +require_once __DIR__ . '/../../../../vendor/autoload.php'; /** * Class to dynamically create an HTML SELECT @@ -103,7 +103,7 @@ function apiVersion() function setSelectedValues($values) { if (is_string($values)) { - $values = split("[ ]?,[ ]?", $values); + $values = explode("[ ]?,[ ]?", $values); } if (!is_array($values)) { $values = array($values); diff --git a/engine/external/pear/MDB2/Driver/mysql.php b/engine/external/pear/MDB2/Driver/mysql.php index 0bf0ab71..10d307de 100644 --- a/engine/external/pear/MDB2/Driver/mysql.php +++ b/engine/external/pear/MDB2/Driver/mysql.php @@ -921,7 +921,7 @@ function &prepare($query, $types = null, $result_types = null, $lobs = array()) } $class_name = 'MDB2_Statement_'.$this->phptype; - $obj =& new $class_name($this, $statement_name, $positions, $query, $types, $result_types, $is_manip, $limit, $offset); + $obj = new $class_name($this, $statement_name, $positions, $query, $types, $result_types, $is_manip, $limit, $offset); $this->debug($query, __FUNCTION__, array('is_manip' => $is_manip, 'when' => 'post', 'result' => $obj)); return $obj; } @@ -1187,7 +1187,7 @@ function &fetchRow($fetchmode = MDB2_FETCHMODE_DEFAULT, $rownum = null) if ($object_class == 'stdClass') { $row = (object) $row; } else { - $row = &new $object_class($row); + $row = new $object_class($row); } } ++$this->rownum; diff --git a/engine/external/pear/MDB2/Driver/mysqli.php b/engine/external/pear/MDB2/Driver/mysqli.php index f49e8eb8..4e18f9c3 100644 --- a/engine/external/pear/MDB2/Driver/mysqli.php +++ b/engine/external/pear/MDB2/Driver/mysqli.php @@ -1151,7 +1151,7 @@ function prepare($query, $types = null, $result_types = null, $lobs = array()) if (!$is_manip) { static $prep_statement_counter = 1; - $statement_name = sprintf($this->options['statement_format'], $this->phptype, $prep_statement_counter++ . sha1(microtime() + mt_rand())); + $statement_name = sprintf($this->options['statement_format'], $this->phptype, $prep_statement_counter++ . sha1(microtime() . strval(mt_rand()))); $statement_name = substr(strtolower($statement_name), 0, $this->options['max_identifiers_length']); $query = "PREPARE $statement_name FROM ".$this->quote($query, 'text'); diff --git a/engine/include.php b/engine/include.php index 2c43a4fa..189eba19 100644 --- a/engine/include.php +++ b/engine/include.php @@ -5,4 +5,4 @@ $include_paths[] = get_include_path(); set_include_path( implode(PATH_SEPARATOR, $include_paths) ); -require_once __DIR__ . '/include/vendor/autoload.php'; \ No newline at end of file +require_once __DIR__ . '/../vendor/autoload.php'; diff --git a/engine/include/CCorpusPerspective.php b/engine/include/CCorpusPerspective.php index 0d3a84e2..4ae2f399 100644 --- a/engine/include/CCorpusPerspective.php +++ b/engine/include/CCorpusPerspective.php @@ -22,6 +22,28 @@ function __construct(CPage &$page) } abstract function execute(); + + // this method is used also by PerspectivePerspectives + function set_users_roles(){ + global $corpus; + $roles = ($this->page->getDb())->fetch_rows("SELECT *" . + " FROM users_corpus_roles us " . + " RIGHT JOIN users u ON (us.user_id=u.user_id AND us.corpus_id={$corpus['id']})" . + " WHERE u.user_id != {$corpus['user_id']}" . + " ORDER BY u.screename"); + + $users_roles = array(); + foreach ($roles as $role){ + $users_roles[$role['user_id']]['role'][] = $role['role']; + $users_roles[$role['user_id']]['screename'] = $role['screename']; + $users_roles[$role['user_id']]['user_id'] = $role['user_id']; + } + foreach($users_roles as $key => $u_roles){ + if(!in_array(CORPUS_ROLE_READ,$u_roles['role'])) + unset($users_roles[$key]); + } + $this->page->set('users_roles', $users_roles); + } // set_users_roles() } ?> diff --git a/engine/include/CInforexWeb.php b/engine/include/CInforexWeb.php index 3122872b..46f5e2d7 100644 --- a/engine/include/CInforexWeb.php +++ b/engine/include/CInforexWeb.php @@ -23,14 +23,18 @@ function __construct() { set_exception_handler('InforexWeb::custom_exception_handler'); - /** - * Activate FireBug-a + /********************************************************************8 + * Aktywuj FireBug-a - only in developement environment + */ + if (class_exists('FB')) { + FB::setEnabled(true); + } + /********************************************************************8 + * Rozpocznij sesję */ - FB::setEnabled(true); - HTTP_Session2::useCookies(true); - HTTP_Session2::start(Config::Config()->get_sid()); - HTTP_Session2::setExpire(time() + Config::Config()->get_session_time()); + HTTP_Session2::start(Config::Cfg()->get_sid()); + HTTP_Session2::setExpire(time() + Config::Cfg()->get_session_time()); } /** @@ -83,7 +87,7 @@ function doAction($action, &$variables) { global $user, $corpus; - include(Config::Config()->get_path_engine() . "/actions/a_{$action}.php"); + include(Config::Cfg()->get_path_engine() . "/actions/a_{$action}.php"); $class_name = "Action_{$action}"; $o = new $class_name(); @@ -118,7 +122,7 @@ function doAjax($ajax, &$variables) header('Content-Type: application/json; charset=utf-8'); /** Process an ajax request */ - $filename = Config::Config()->get_path_engine() . "/ajax/ajax_{$ajax}.php"; + $filename = Config::Cfg()->get_path_engine() . "/ajax/ajax_{$ajax}.php"; if (!file_exists($filename)) { echo $this->ajaxError("ERROR_APPLICATION", "Ajax not found: " . $filename); return; @@ -158,7 +162,7 @@ function doPage($page, &$variables) $page = $page ? $page : 'home'; // If the required module does not exist, change it silently to the default. - $pageFile = Config::Config()->get_path_engine() . "/page/page_{$page}.php"; + $pageFile = Config::Cfg()->get_path_engine() . "/page/page_{$page}.php"; if (!file_exists($pageFile)) { return $this->doPage("home", $variables); } @@ -178,7 +182,7 @@ function doPage($page, &$variables) $o->set('page', $page); $o->set('corpus', $corpus); $o->set('release', defined("RELEASE") ? RELEASE : "RELEASE" ); - $o->set('config', Config::Config()); + $o->set('config', Config::Cfg()); $o->set('rev', $this->getRevisionKey()); $access = $o->hasAccess($user, $corpus); @@ -193,10 +197,10 @@ function doPage($page, &$variables) $o->set('warnings', $o->getWarnings()); $o->set('exceptions', $variables['exceptions']); $o->set('Config', array( - "log_sql" => Config::Config()->get_log_sql(), - "url" => Config::Config()->get_url(), - "wccl_match_enable" => Config::Config()->get_wccl_match_enable(), - "federationLoginUrl" => Config::Config()->get_federationLoginUrl() + "log_sql" => Config::Cfg()->get_log_sql(), + "url" => Config::Cfg()->get_url(), + "wccl_match_enable" => Config::Cfg()->get_wccl_match_enable(), + "federationLoginUrl" => Config::Cfg()->get_federationLoginUrl() )); foreach ($variables as $k => $v) { $o->set($k, $v); @@ -245,14 +249,14 @@ function execute() /* Gather the data about an activity */ $activity_page = array(); - $activity_page['ip_id'] = $db->get_entry_key("ips", "ip_id", array("ip" => $_SERVER["REMOTE_ADDR"])); + $activity_page['ip_id'] = $db->get_entry_key("ips", "ip_id", array("ip" => isset($_SERVER["REMOTE_ADDR"]) ? $_SERVER["REMOTE_ADDR"] : "CLI local" )); $activity_page['user_id'] = isset($user) ? $user['user_id'] : null; $activity_page['corpus_id'] = isset($corpus['id']) ? $corpus['id'] : null; $activity_page['report_id'] = RequestLoader::getDocumentId(); $activity_page['datetime'] = date("Y-m-d H:i:s"); try { - if ($action && file_exists(Config::Config()->get_path_engine() . "/actions/a_{$action}.php")) { + if ($action && file_exists(Config::Cfg()->get_path_engine() . "/actions/a_{$action}.php")) { $page = $this->doAction($action, $variables); $activity_page['activity_type_id'] = $db->get_entry_key("activity_types", "activity_type_id", array("name" => $action, "category" => "action")); $activity_page['execution_time'] = time() - $stamp_start; diff --git a/engine/include/CPage.php b/engine/include/CPage.php index ca1a806a..5181a3ff 100644 --- a/engine/include/CPage.php +++ b/engine/include/CPage.php @@ -73,12 +73,12 @@ class CPage extends CRequest{ */ var $include_files = array(); - function CPage($name=null,$description=null){ + function __construct($name=null,$description=null){ $this->name = $name; $this->description = $description; $this->template = new Smarty(); - $this->template->compile_dir = Config::Config()->get_path_engine() . "/templates_c"; - $this->set('RELEASE', "RELEASE"); + $this->template->compile_dir = Config::Cfg()->get_path_engine() . "/templates_c"; + $this->set('RELEASE', defined('RELEASE') ? RELEASE : "RELEASE"); /** * Include default JS and CSS files for the page @@ -92,13 +92,13 @@ function CPage($name=null,$description=null){ if ( substr($className, 0, 5) == "Page_"){ $this->includeJs("js/page.js"); $page = str_replace("Page_", "", $className); - if (file_exists(Config::Config()->get_path_www() . "/js/page_{$page}.js")){ + if (file_exists(Config::Cfg()->get_path_www() . "/js/page_{$page}.js")){ $this->includeJs("js/page_{$page}.js"); } - if (file_exists(Config::Config()->get_path_www() . "/js/page_{$page}_resize.js")){ + if (file_exists(Config::Cfg()->get_path_www() . "/js/page_{$page}_resize.js")){ $this->includeJs("js/page_{$page}_resize.js"); } - if (file_exists(Config::Config()->get_path_www() . "/css/page_{$page}.css")){ + if (file_exists(Config::Cfg()->get_path_www() . "/css/page_{$page}.css")){ $this->includeCss("css/page_{$page}.css"); } } @@ -152,7 +152,11 @@ function hasAccess($user=null, $corpus=null){ return true; } else { - $userCorpusRoles = is_array($corpus['role'][$user['user_id']]) ? array_keys($corpus['role'][$user['user_id']]) : array(ROLE_SYSTEM_USER_PUBLIC); + if(isset($corpus['role'][$user['user_id']])) { + $userCorpusRoles = is_array($corpus['role'][$user['user_id']]) ? array_keys($corpus['role'][$user['user_id']]) : array(ROLE_SYSTEM_USER_PUBLIC); + } else { + $userCorpusRoles = array(ROLE_SYSTEM_USER_PUBLIC); + } $rolesRequired = array_merge($rolesRequired, $this->anyCorpusRole); $rolesUser = array_merge($rolesUser, $userCorpusRoles); @@ -163,7 +167,11 @@ function hasAccess($user=null, $corpus=null){ if ( hasUserSystemRole($user, $this->anySystemRole) ){ return true; } else { - $userSystemRoles = is_array($user['role']) ? array_keys($user['role']) : array(ROLE_SYSTEM_USER_PUBLIC=>""); + if(isset($user['role'])) { + $userSystemRoles = is_array($user['role']) ? array_keys($user['role']) : array(ROLE_SYSTEM_USER_PUBLIC=>""); + } else { + $userSystemRoles = array(ROLE_SYSTEM_USER_PUBLIC=>""); + } $rolesRequired = array_merge($rolesRequired, $this->anySystemRole); $rolesUser = array_merge($rolesUser, $userSystemRoles); } @@ -217,8 +225,8 @@ function set_by_ref($name, &$object){ * @param $name -- a variable name * @return variable value or null if the variable is undefined * or array of all template variables if $name=null - */ - function get($name){ + */ + function get($name){ if(method_exists($this->template,"getTemplateVars" )) { // Smarty version 3+ return $this->template->getTemplateVars($name); } else { // Smarty version below 3 @@ -257,7 +265,7 @@ function execute(){} */ function display($template_name){ $this->set("include_files", $this->include_files); - $this->template->display(Config::Config()->get_path_engine() . "/templates/page_{$template_name}.tpl"); + $this->template->display(Config::Cfg()->get_path_engine() . "/templates/page_{$template_name}.tpl"); } /** diff --git a/engine/include/CRequest.php b/engine/include/CRequest.php index 8ef211da..fed3818f 100644 --- a/engine/include/CRequest.php +++ b/engine/include/CRequest.php @@ -28,7 +28,7 @@ function getRequestParameterRequired($name) if (isset($_REQUEST[$name])) { return $_REQUEST[$name]; } else { - throw new Exception("Missing parameter in the request: $name"); + throw new CRequestException("Missing parameter in the request: $name"); } } diff --git a/engine/include/CUserAuthorize.php b/engine/include/CUserAuthorize.php index 55561812..bea975f4 100644 --- a/engine/include/CUserAuthorize.php +++ b/engine/include/CUserAuthorize.php @@ -35,6 +35,10 @@ function getUserData(){ // Pobierz role użytkownika if ($user){ $roles = $db->fetch_rows("SELECT * FROM users_roles us JOIN roles USING (role) WHERE user_id=?", array($user['user_id'])); + + $login = $db->fetch_one("SELECT login FROM users WHERE user_id=?", array($user['user_id'])); + $user['login'] = $login; + $user['role'][ROLE_SYSTEM_USER_PUBLIC] = "Has access to public pages"; $user['role'][ROLE_SYSTEM_USER_LOGGEDIN] = "User is loggedin to the system"; foreach ($roles as $role){ @@ -48,7 +52,7 @@ function getUserData(){ } function redirectToClarinLogin(){ - header('Location: '.Config::Config()->get_federationLoginUrl()."http://".$_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"]); + header('Location: '.Config::Cfg()->get_federationLoginUrl()."http://".$_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"]); } function logInClarinUser($userClarin){ @@ -72,26 +76,35 @@ function getClarinUser(){ // sudo apt-get install php5-curl if(isset($_COOKIE['clarin-pl-token'])) { - $token = $_COOKIE['clarin-pl-token']; - $curl = curl_init(Config::Config()->get_federationValidateTokenUrl() . $token); + return $this->getClarinUserByToken($_COOKIE['clarin-pl-token']); + } else { + return null; + } - curl_setopt($curl, CURLOPT_POST, true); - curl_setopt($curl, CURLOPT_POSTFIELDS, ''); - curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type:application/json')); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + } // getClarinUser() - $response = curl_exec($curl); - $httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE); - curl_close($curl); + private function getClarinUserByToken($token){ - // invalid token - if ($httpcode !== 200) { - return null; - } - return json_decode($response, true); + // using system curl command + // sudo apt-get install php5-curl + $curl = curl_init(Config::Cfg()->get_federationValidateTokenUrl() . $token); + + curl_setopt($curl, CURLOPT_POST, true); + curl_setopt($curl, CURLOPT_POSTFIELDS, ''); + curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type:application/json')); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + + $response = curl_exec($curl); + $httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE); + curl_close($curl); + + // invalid token + if ($httpcode !== 200) { + return null; } - return null; - } + return json_decode($response, true); + + } // getClarinUserByToken() function getClarinLogin() { diff --git a/engine/include/class/TableReport.php b/engine/include/class/TableReport.php index b607bede..23d8d88e 100644 --- a/engine/include/class/TableReport.php +++ b/engine/include/class/TableReport.php @@ -64,7 +64,7 @@ public function validateSchema(){ $parse = HtmlParser::parseXml($this->content); break; case "premorph": - $parse = HtmlParser::validateXmlWithXsd($this->content, Config::Config()->get_path_engine()."/resources/synat/premorph.xsd"); + $parse = HtmlParser::validateXmlWithXsd($this->content, Config::Cfg()->get_path_engine()."/resources/synat/premorph.xsd"); break; default: $parse = array(); diff --git a/engine/include/database/CDbAnnotation.php b/engine/include/database/CDbAnnotation.php index a11aa456..c16e12cf 100755 --- a/engine/include/database/CDbAnnotation.php +++ b/engine/include/database/CDbAnnotation.php @@ -166,7 +166,7 @@ static function getAnnotationTypesBySets($report_ids, $relation_ids){ static function getAnnotationsBySets($report_ids=null, $annotation_layers=null, $annotation_names=null, $stage = null){ global $db; - $sql = "SELECT *, raa.`value` AS `prop` " . + $sql = "SELECT ra.*, at.*, raa.annotation_id, raa.annotation_attribute_id, raa.`user_id` AS `attr_user_id`, raa.`value` AS `prop` " . " FROM reports_annotations ra" . " LEFT JOIN annotation_types at ON (ra.type=at.name) " . " LEFT JOIN reports_annotations_attributes raa ON (ra.id=raa.annotation_id) "; @@ -203,7 +203,7 @@ static function getAnnotationsBySets($report_ids=null, $annotation_layers=null, */ static function getAnnotationsBySubsets($report_ids=null, $annotation_subset_ids=null){ global $db; - $sql = "SELECT *, ra.type, raa.`value` AS `prop` " . + $sql = "SELECT ra.*, at.*, raa.annotation_id, raa.annotation_attribute_id, raa.`user_id` AS `attr_user_id`, raa.`value` AS `prop` " . " FROM reports_annotations ra" . " LEFT JOIN annotation_types at ON (ra.type=at.name) " . " LEFT JOIN reports_annotations_attributes raa ON (ra.id=raa.annotation_id) "; @@ -767,29 +767,62 @@ static function getAnnotationTags($corpus_id, $annotation_type, $session){ return $db->fetch_rows($sql, $params); } - static function getAnnotationStructureByCorpora($corpus_id){ + static private function annotationStructureFromDBToArrayTree($dbResult,$limited = false) { + + if($limited){ + // key for this array is [set_id,subset_id] + $typesCountForSetSubset = array(); + $maxTypesLimitThreshold = Config::Cfg()->get_max_types_limit_threshold(); + } + + $annotation_sets = array(); + foreach($dbResult as $at){ + $set_id = $at['set_id']; + $subset_id = $at['subset_id']; // may be null + if (!isset($annotation_sets[$set_id])){ + $annotation_sets[$set_id] = array('name' => $at['set_name']); + } + if(isset($subset_id)) { + if (!isset($annotation_sets[$set_id][$subset_id])){ + $annotation_sets[$set_id][$subset_id] = array('name' => $at['subset_name']); + } + + if($limited){ + // counts types for set,subset + $typesCountForSetSubset[$set_id][$subset_id] = 1 + + ( isset($typesCountForSetSubset[$set_id][$subset_id]) + ? $typesCountForSetSubset[$set_id][$subset_id] : 0 ); + // test threshold + if($typesCountForSetSubset[$set_id][$subset_id] + == $maxTypesLimitThreshold ) { + $annotation_sets[$set_id][$subset_id][MAX_TYPES_LABEL_INDEX] = MAX_TYPES_NAME_LABEL; + } + if($typesCountForSetSubset[$set_id][$subset_id] + < $maxTypesLimitThreshold ) { + $annotation_sets[$set_id][$subset_id][$at['type_id']] = $at['type_name']; + } + } else { + // old method generating very big html structure + $annotation_sets[$set_id][$subset_id][$at['type_id']] = $at['type_name']; + } // if !limited + } // $subset_id!=null + + } // foreach() + + return $annotation_sets; + + } // annotationStructureFromDBToArrayTree + + static function getAnnotationStructureByCorpora($corpus_id,$limited = false){ global $db; $sql = "SELECT ans.annotation_set_id AS set_id, ans.name AS set_name, ansub.annotation_subset_id AS subset_id, ansub.name AS subset_name, at.name AS type_name, at.annotation_type_id AS type_id FROM annotation_types at LEFT JOIN annotation_subsets ansub ON ansub.annotation_subset_id=at.annotation_subset_id LEFT JOIN annotation_sets ans ON ans.annotation_set_id=at.group_id LEFT JOIN annotation_sets_corpora ac ON ac.annotation_set_id=ans.annotation_set_id WHERE ac.corpus_id = ?"; $annotation_types = $db->fetch_rows($sql,array($corpus_id)); - $annotation_sets = array(); - foreach($annotation_types as $at){ - $set_id = $at['set_id']; - $subset_id = $at['subset_id']; - if (!isset($annotation_sets[$set_id])){ - $annotation_sets[$set_id] = array('name' => $at['set_name']); - } - if($subset_id!=null){ - if (!isset($annotation_sets[$set_id][$subset_id])){ - $annotation_sets[$set_id][$subset_id] = array('name' => $at['subset_name']); - } - $annotation_sets[$set_id][$subset_id][$at['type_id']] = $at['type_name']; - } // $subset_id!=null - } - return $annotation_sets; - } + return self::annotationStructureFromDBToArrayTree($annotation_types,$limited); + + } // getAnnotationStructureByCorpora() /* * for one integer $corpus_id returns list of all annotation sets @@ -964,7 +997,7 @@ static function getUserAnnotationCount($corpus_id=null, $subcorpus_ids=null, $re } if ( $annotation_type_ids !== null ){ - $annotation_type_ids = array_map(intval, $annotation_type_ids); + $annotation_type_ids = array_map('intval', $annotation_type_ids); if ( count($annotation_type_ids) > 0 ){ $params_where = array_merge($params_where, $annotation_type_ids); $sql_where[] = "a.type_id IN (" . implode(",", array_fill(0, count($annotation_type_ids), "?")) .")"; @@ -1042,7 +1075,7 @@ static function getUserAnnotations($user_id=null, $corpus_id=null, $subcorpus_id } if ( $annotation_type_ids !== null ){ - $annotation_type_ids = array_map(intval, $annotation_type_ids); + $annotation_type_ids = array_map('intval', $annotation_type_ids); if ( count($annotation_type_ids) > 0 ){ $params_where = array_merge($params_where, $annotation_type_ids); $sql_where[] = "a.type_id IN (" . implode(",", array_fill(0, count($annotation_type_ids), "?")) .")"; @@ -1119,7 +1152,7 @@ static function getAnnotationCount($user_id=null, $corpus_id=null, $subcorpus_id } if ( $annotation_type_ids !== null ){ - $annotation_type_ids = array_map(intval, $annotation_type_ids); + $annotation_type_ids = array_map('intval', $annotation_type_ids); if ( count($annotation_type_ids) > 0 ){ $params_where = array_merge($params_where, $annotation_type_ids); $sql_where[] = "a.type_id IN (" . implode(",", array_fill(0, count($annotation_type_ids), "?")) .")"; @@ -1252,7 +1285,7 @@ static function getAnnotationDocCount($user_id=null, $corpus_id=null, $subcorpus } if ( $annotation_type_ids !== null ){ - $annotation_type_ids = array_map(intval, $annotation_type_ids); + $annotation_type_ids = array_map('intval', $annotation_type_ids); if ( count($annotation_type_ids) > 0 ){ $params_where = array_merge($params_where, $annotation_type_ids); $sql_where[] = "a.type_id IN (" . implode(",", array_fill(0, count($annotation_type_ids), "?")) .")"; diff --git a/engine/include/database/CDbAnnotationSharedAttribute.php b/engine/include/database/CDbAnnotationSharedAttribute.php index df5d3cc4..20fab316 100644 --- a/engine/include/database/CDbAnnotationSharedAttribute.php +++ b/engine/include/database/CDbAnnotationSharedAttribute.php @@ -8,43 +8,43 @@ class CDbAnnotationSharedAttribute{ - function getAll(){ + static function getAll(){ global $db; $sql = "SELECT * FROM shared_attributes ORDER BY description"; return $db->fetch_rows($sql); } - function get($sharedAttributeId){ + static function get($sharedAttributeId){ global $db; $sql = "SELECT * FROM shared_attributes WHERE id = ?"; return $db->fetch($sql, array($sharedAttributeId)); } - function existsAttributeEnumValue($sharedAttributeId, $value){ + static function existsAttributeEnumValue($sharedAttributeId, $value){ global $db; $sql = "SELECT * FROM shared_attributes_enum WHERE shared_attribute_id = ? AND `value` = ?"; return count($db->fetch_rows($sql, array($sharedAttributeId, $value)))>0; } - function addAttributeEnumValue($sharedAttributeId, $value){ + static function addAttributeEnumValue($sharedAttributeId, $value){ global $db; $sql = "INSERT IGNORE INTO shared_attributes_enum (shared_attribute_id, `value`) VALUES(?, ?)"; $db->execute($sql, array($sharedAttributeId, $value)); } - function addAttributeEnumValueWithDescription($sharedAttributeId, $value, $description){ + static function addAttributeEnumValueWithDescription($sharedAttributeId, $value, $description){ global $db; $sql = "INSERT INTO shared_attributes_enum (shared_attribute_id, `value`, description) VALUES(?, ?, ?)"; $db->execute($sql, array($sharedAttributeId, $value, $description)); } - function deleteAttributeValue($attributeId, $value){ + static function deleteAttributeValue($attributeId, $value){ global $db; $sql = "DELETE FROM shared_attributes_enum WHERE shared_attribute_id=? AND value=?"; $db->execute($sql, array($attributeId, $value)); } - function getAnnotationSharedAttributes($annotationId){ + static function getAnnotationSharedAttributes($annotationId){ global $db; $sql = "SELECT atsa.*, sa.*, rasa.value FROM reports_annotations_shared_attributes rasa JOIN shared_attributes sa ON rasa.shared_attribute_id = sa.id @@ -54,7 +54,7 @@ function getAnnotationSharedAttributes($annotationId){ return $db->fetch_rows($sql, array($annotationId)); } - function getAttributeAnnotationValues($corpusId, $attributeId=null, $lang=null, $subcorpusId=null){ + static function getAttributeAnnotationValues($corpusId, $attributeId=null, $lang=null, $subcorpusId=null){ global $db; $builder = new SqlBuilder("reports_annotations_shared_attributes", "rasa"); $builder->addSelectColumn(new SqlBuilderSelect("rasa.value", "value")); @@ -81,7 +81,7 @@ function getAttributeAnnotationValues($corpusId, $attributeId=null, $lang=null, return $db->fetch_rows($sql, $params); } - function getAnnotationsWithAttributeValue( + static function getAnnotationsWithAttributeValue( $corpusId, $attributeId=null, $attributeValue=null, $lang=null, $subcorpusId=null){ global $db; $builder = new SqlBuilder("reports_annotations_shared_attributes", "rasa"); @@ -118,21 +118,21 @@ function getAnnotationsWithAttributeValue( return $db->fetch_rows($sql, $params); } - function updateAttributeDescription($attributeId, $value, $description){ + static function updateAttributeDescription($attributeId, $value, $description){ global $db; $sql = "UPDATE shared_attributes_enum SET description = ? WHERE shared_attribute_id = ? AND value = ?"; $db->execute($sql, array($description, $attributeId, $value)); } - function updateAttributeValue($attributeId, $valueOld, $valueNew){ + static function updateAttributeValue($attributeId, $valueOld, $valueNew){ global $db; $sql = "UPDATE shared_attributes_enum SET value = ? WHERE shared_attribute_id = ? AND value = ?"; $db->execute($sql, array($valueNew, $attributeId, $valueOld)); } - function updateAnnotationAttributeValues($attributeId, $valueOld, $valueNew){ + static function updateAnnotationAttributeValues($attributeId, $valueOld, $valueNew){ global $db; $sql = "UPDATE reports_annotations_shared_attributes SET value = ? WHERE shared_attribute_id = ? AND value = ?"; $db->execute($sql, array($valueNew, $attributeId, $valueOld)); } -} \ No newline at end of file +} diff --git a/engine/include/database/CDbCorpus.php b/engine/include/database/CDbCorpus.php index 4b4131e7..c87926c9 100644 --- a/engine/include/database/CDbCorpus.php +++ b/engine/include/database/CDbCorpus.php @@ -333,8 +333,9 @@ static function getCorpusExtColumns($table_name){ if (preg_match('/^enum\((.*)\)$/', $row['Type'], $match)){ $field['type'] = 'enum'; $values = array(); - foreach ( split(",", $match[1]) as $v ) - $values[] = trim($v, "'"); + foreach ( preg_split("~,~", $match[1]) as $v ) { + $values[] = trim($v, "'"); + } $field['field_values'] = $values; } else diff --git a/engine/include/database/CDbImage.php b/engine/include/database/CDbImage.php index a7d22993..cc1fec2c 100644 --- a/engine/include/database/CDbImage.php +++ b/engine/include/database/CDbImage.php @@ -41,7 +41,7 @@ static function deleteImage($image_id, $image_name){ $sql = "DELETE FROM images WHERE id = ?"; $db->execute($sql, array($image_id)); - $image_path = Config::Config()->get_path_www() . "/images/" . $image_id . "_" . $image_name; + $image_path = Config::Cfg()->get_path_www() . "/images/" . $image_id . "_" . $image_name; if (file_exists($image_path)) { unlink($image_path); } diff --git a/engine/include/database/CDbRelationSet.php b/engine/include/database/CDbRelationSet.php index 79d8306e..75faceb8 100644 --- a/engine/include/database/CDbRelationSet.php +++ b/engine/include/database/CDbRelationSet.php @@ -34,11 +34,12 @@ static function getRelationTypesOfSet($relation_set_id, $report_id = null){ $params = array($relation_set_id); $relation_types = $db->fetch_rows($sql, $params); + $report_sql = ""; if($report_id != null){ $report_sql = "AND rao_src.report_id = ? AND rao_trg.report_id = ?"; } - $sql = "SELECT r.*, COUNT(r.id) AS 'number_of_types' FROM relation_types rt + $sql = "SELECT COUNT(r.id) AS 'number_of_types' FROM relation_types rt LEFT JOIN relations r ON r.relation_type_id = rt.id LEFT JOIN reports_annotations_optimized rao_src ON rao_src.id = r.source_id LEFT JOIN reports_annotations_optimized rao_trg ON rao_trg.id = r.target_id diff --git a/engine/include/database/Database.php b/engine/include/database/Database.php index cbb3b92e..35890d1f 100644 --- a/engine/include/database/Database.php +++ b/engine/include/database/Database.php @@ -6,59 +6,49 @@ * See LICENCE */ -// dla dostępności MDB2::MDB2_PORTABILITY_NONE przy inicjowaniu $db tylko -require_once(__DIR__."/../../../engine/external/pear/MDB2.php"); - /** * Database gateway. */ class Database{ - var $mdb2 = null; + private $mdb2 = null; // instance of IDatabaseEngine class var $log = false; + private $_encoding = "utf8mb4"; + /** * @param dsn {array} * @param log {boolean} -- print logs (default: false) * @param log_output {String} -- where to print logs: fb (use fb function), print (use print), */ - function __construct($dsn, $log=false, $log_output="chrome_php", $encoding="utf8mb4"){ - $options = array('portability' => MDB2_PORTABILITY_NONE); - $options['debug']=2; - $options['result_buffering']=false; - // to eliminate some problems with prepare statements - $options['emulate_prepared']=true; - $this->mdb2 = MDB2::connect($dsn, $options); - if (PEAR::isError($this->mdb2)) { - throw new DatabaseException($this->mdb2->getMessage()); + public function __construct($dsn, $log=false, $log_output="chrome_php", $encoding="utf8mb4"){ + // mysql library driver is not supported in PHP 7.x at all + if(array_key_exists('phptype',$dsn) + && ($dsn['phptype']=='mysql') + && version_compare(phpversion(),'7.0.0','>=') + ) { + throw new DatabaseException("Driver 'mysql' is not supported in PHP7, check your configuration 'phptype' setting, try using 'mysqli'."); } - $this->mdb2->loadModule('Extended'); + $this->mdb2 = new MDB2DatabaseEngine($dsn); $this->set_encoding($encoding); - // line below catch only warning. Doesn't work w/o db server restart - //$this->mdb2->query("SET SESSION query_cache_type = ON"); $this->log = $log; $this->log_output = $log_output; } - /** - * Log out and disconnect from the database. - */ - function disconnect(){ - $this->mdb2->disconnect(); - } - /** * reset encoding to comunicate with database */ public function set_encoding($encoding) { - $this->mdb2->query("SET CHARACTER SET '$encoding'"); - $this->mdb2->query("SET NAMES '$encoding'"); + $this->_encoding = $encoding; + // SET CHARACTER SET sets only subset of SET NAMES params + //$this->execute("SET CHARACTER SET '$encoding'"); + $this->execute("SET NAMES '$encoding'"); } // set_encoding() /** * Log message using Database internal logger. */ - function log_message($message){ + private function log_message($message){ if ( $this->log ){ if ($this->log_output == "print"){ print '
\n'.$message.'
\n'; @@ -74,13 +64,18 @@ function log_message($message){ * @param $sql {String} SQL query. * @param $args {Array} Query arguments */ - function log_sql($sql, $args){ + private function log_sql($sql, $args){ if ( $this->log ){ $backtrace = array(); foreach (debug_backtrace() as $d){ +// When use register_shutdown_function, and the function called when shutting down, there are no line number nor filename information about this function, only function, class(if possible), type(if possible) and args are provided. We must provides service for potentialy missing index $backtrace[] = sprintf("File %s, line %d, %s%s%s(...)", - $d['file'], $d['line'], $d['class'], $d['type'], - $d['function']); + (isset($d['file']) ? $d['file'] : __FILE__), + (isset($d['line']) ? $d['line'] : ""), + (isset($d['class']) ? $d['class'] : ""), + (isset($d['type']) ? $d['type'] : ""), + (isset($d['function']) ? $d['function'] : "") + ); } if ($this->log_output == "print"){ @@ -95,7 +90,10 @@ function log_sql($sql, $args){ ChromePhp::log($args); ChromePhp::log($backtrace); } - elseif ($this->log_output == "fb"){ + // FB class included only in dev environment + elseif ( ($this->log_output == "fb") + && (class_exists('FB')) + ) { FB::info($sql, "SQL LOG"); fb($args, "Args"); fb($backtrace, "Backtrace"); @@ -110,58 +108,49 @@ function log_sql($sql, $args){ * Execute query with optional argument and return result of the execution. * @param $sql {String} SQL query. * @param $args {Array} Query argumnets. + * + * @returns MDB2_Result_Common object + * any error is converted to DatabaseException, which should be catched + * */ function execute($sql, $args=null){ $time_start = microtime(TRUE); - $sth = null; $result = null; try{ $this->log_sql($sql, $args); - if ($args == null){ - if (PEAR::isError($result = $this->mdb2->query($sql))){ - print("
{$result->getUserInfo()}
"); - throw new DatabaseException($result->getMessage()); - } - }else{ - if (PEAR::isError($sth = $this->mdb2->prepare($sql))){ - print("
{$sth->getUserInfo()}
"); - throw new DatabaseException($sth->getMessage()); - } - $result = $sth->execute($args); - if (PEAR::isError($result)){ - throw new DatabaseException($result->getMessage() . "\n" . $result->getUserInfo(), $result); - } - if ($this->log){ - $this->log_message($args, "SQL DATA"); - } + if ($this->log){ + $this->log_message($args, "SQL DATA"); } + $result=$this->mdb2->prepareAndExecute($sql,$args); if ($this->log) $this->log_message('Execute time: '.number_format(microtime(TRUE)-$time_start, 6).' s.', "SQL"); } - catch(Exception $ex){ - if ( $sth !== null && !PEAR::isError($sth) ){ - $sth->free(); - } - throw $ex; + catch(DatabaseException $ex){ + // re-throw it as-is + throw new DatabaseException($ex->getMessage(),$ex->getDetails()); } - if ( $sth !== null && !PEAR::isError($sth) ){ - $sth->free(); + catch(Exception $ex){ + // rethrow all other exception as DatabaseExceptions + throw new DatabaseException($ex->getMessage()); } + return $result; - } + + } // execute /** - * Execute query and return result as an assoc array. + * Execute query and return result as an array of assoc arrays. * @param $sql {String} SQL query. * @param $args {Array} Query arguments. * @return {Array} Array of arrays (rows) + * or DatabaseException on error */ function fetch_rows($sql, $args = null){ - return $this->execute($sql, $args)->fetchAll(MDB2_FETCHMODE_ASSOC); + return $this->execute($sql, $args)->fetchAll(); } /** - * Return one-dimensional array of values for given column for each row + * Return one-dimensional array of values from given column for each row * returned by the query. * @param $sql {String} SQL query. * @param $column {String} Column name. @@ -177,7 +166,7 @@ function fetch_ones($sql, $column, $args = null){ } else { // error throw new DatabaseException( "Column $column doesn't exists in results of $sql query.", - array( "sql"=>$sql, + array( "sql"=>$sql, "column" => $column, "args" => $args ) @@ -187,13 +176,13 @@ function fetch_ones($sql, $column, $args = null){ return $vals; } - /** * Return a one-dimensional array of values representing a single row * returned by the query. * @param $sql {String} SQL query. * @param $args {Array} Query arguments. - * @return {Array} An assoc array of strings. + * @return {Array} An assoc array of strings ( may be empty ) + * DatabaseException thrown on error */ function fetch($sql, $args=null){ $result = $this->fetch_rows($sql,$args); @@ -201,24 +190,26 @@ function fetch($sql, $args=null){ } - /** * Return a single value for the first row. + * @param $sql {String} SQL query. + * @param $args {Array} Query arguments. + * @return one scalar value or null if result is empty + * DatabaseException thrown on error */ function fetch_one($sql, $args=null){ - $r = $this->execute($sql, $args); - return $r->fetchOne(); - } - /** - * - */ - function fetch_id($table_name){ - return $this->mdb2->getAfterID(0, $table_name); + $result = $this->fetch($sql,$args); + // select list of values from assoc array, and get first one + // or null if empty + return is_array($result) && (count($result)>0) ? array_values($result)[0] : null ; + } /** * + * returns string type because of type of autoincrement field may + * be BIGINT */ function last_id(){ return $this->mdb2->lastInsertID(); @@ -229,9 +220,10 @@ function last_id(){ * @param table Name of a table. * @param values Assoc array with values to update, i.e. array("column"=>"value") * @param keys Assoc array with keys, i.e. array("key"=>"value") + * DatabaseException thrown on error */ function update($table, $values, $keys){ - $value = ""; + $value = array(); if(is_array($values)){ foreach ($values as $k=>$v) $value[] = "`$k`=?"; @@ -242,7 +234,7 @@ function update($table, $values, $keys){ // followed implode() fails.... throw new DatabaseException("2-nd argument of Database->update() must be non empty array.",$values); } - $key = ""; + $key = array(); if(is_array($keys)){ foreach ($keys as $k=>$v) $key[] = "`$k`=?"; @@ -258,11 +250,11 @@ function update($table, $values, $keys){ $this->execute($sql, $args); } - /** * Inserts a row with values to given table. * @param $table Name of a table - * @param $attributes Assoc table with colument and values, i.e. array("column"=>"value") + * @param $values Assoc table with columns and values, i.e. array("column"=>"value") + * DatabaseException thrown on error */ function insert($table, $values){ $cols = array(); @@ -288,26 +280,8 @@ function insert($table, $values){ * @param $table Name of a table * @param $columns Array with column names. * @param $values Array of array of column values. + * DatabaseException thrown on error */ - /* function insert_bulk($table, $columns, $values){ - $params = array(); - $cols = array(); - $fs = array(); - foreach ($columns as $column){ - $cols[] = "`$column`"; - $fs[] = "?"; - } - $field = "(".implode(", ", $fs).")"; - $fields = array(); - foreach ($values as $vs){ - foreach ($vs as $v){ - $params[] = $v; - } - $fields[] = $field; - } - $sql = "INSERT INTO $table(".implode(",", $cols).") VALUES ".implode(",", $fields); - $this->execute($sql, $params); - } */ function insert_bulk($table, $columns, $values){ $params = array(); $cols = array(); @@ -340,9 +314,11 @@ function insert_bulk($table, $columns, $values){ $this->execute($sql, $params); } - /** * Insert or replace row for the keys. + * @param $table Name of a table + * @param $values Assoc table with columns and values, i.e. array("column"=>"value") + * DatabaseException thrown on error */ function replace($table, $values){ $value = array(); @@ -360,17 +336,13 @@ function replace($table, $values){ $this->execute($sql, $params); } - - /* function select($table, $values){ - $value = array(); - $params = array(); - foreach ($values as $k=>$v){ - $value[] = "`$k`=?"; - $params[] = $v; - } - $sql = "SELECT * FROM `$table` WHERE ".implode(" AND ", $value); - return $this->fetch_rows($sql, $params); - }*/ + /** + * fetch rows for the keys. + * @param $table Name of a table + * @param $values Assoc table with columns and values, i.e. array("column"=>"value") + * @return {Array} Array of arrays (rows) + * or DatabaseException on error + */ function select($table, $values){ $value = array(); $params = array(); @@ -387,11 +359,13 @@ function select($table, $values){ return $this->fetch_rows($sql, $params); } - /** * @param $table * @param $keyColumn * @param $values + * + * @return one scalar value + * DatabaseException on error */ function get_entry_key($table, $keyColumn, $values){ $sql = "SELECT $keyColumn FROM $table"; @@ -426,17 +400,6 @@ function get_entry_key($table, $keyColumn, $values){ * @return {Array} Array of instance of $class_name with attributtes * sets to name and values from selected rows */ - /* public function fetch_class_rows($class_name, $sql, $args = null){ - $rows = $this->fetch_rows($sql, $args); - $objects = array(); - foreach ($rows as $row){ - $o = new $class_name(); - foreach ($row as $k=>$v) - $o->$k = $v; - $objects[] = $o; - } - return $objects; - } // fetch_class_rows() */ public function fetch_class_rows($class_name, $sql, $args = null){ if(!class_exists($class_name)) { throw new DatabaseException('First argument of fetch_class_rows method from Database class must be a valid class name'); @@ -452,41 +415,75 @@ public function fetch_class_rows($class_name, $sql, $args = null){ return $objects; } // fetch_class_rows() - /** * Convert a text value into a DBMS specific format that is suitable to * compose query statements. * * @param string text string value that is intended to be converted. - * @param string type to which the value should be converted to - * @param bool quote - * @param bool escape wildcards * * @return string text string that represents the given argument value in * a DBMS specific format. */ - public function quote($value, $type = null, $quote = true, $escape_wildcards = false) + public function quote($stringValue) { - return $this->mdb2->quote($value,$type,$quote,$escape_wildcards); + + $stringValue = $this->escape($stringValue); + return "'".$stringValue."'"; + } - // TODO: check strictly and replace by other implemented methods - public function fetchAll($sql) { - return $this->mdb2->query($sql)->fetchAll(); - } // fetchAll() + /* Umieszcza prefix escapowania ('\') przed znakami tego wymagajacymi + * w tekście $text, aby mógł być bezpiecznie użyty w treści zapytań SQL. + * Wymaganie implementacyjne jest takie, że $this->mdb2-getConnection() + * musi być działającym połączeniem do bazy, bo inaczej zwróci ''. + * Wynika to z konieczności odczytania charset z bazy i dostosowania + * eskejpowanych znaków do aktualnego charsetu. Odbywa się to tutaj + * niejawnie ( ugh... :o( ), co może prowadzić do niejasnych zachowań + * + * @param string the input string to quote + * + * @return string quoted string + * + * @access private + */ + + public function escape($text) { + + return $this->mdb2->escape($text); + + } // escape() - // TODO: change to something more flexible after checking in tests + /** + * Execute query and return result as one-dimensional array + * of one-dimensional arrays ( lists ) from each row found + * @param $sql {String} SQL query. + * @return {Array} Array of non-associative arrays from selected rows + */ + public function fetchOneListForEachRow($sql) { + + $allRowsAsListOfAssoc = $this->fetch_rows($sql); + $result = array(); + foreach($allRowsAsListOfAssoc as $rowAsAssoc) { + $result[]=array_values($rowAsAssoc); + } + return $result; + + } // fetchOneListForEachRow + + /** + * This method is used to collect information about an error + * + * @return array with MDB2 errorcode, native error code, native message + * + */ + // TODO: change to something more universal after checking in tests public function errorInfo() { return $this->mdb2->errorInfo(); } // errorInfo() - public function escape($text) { - - return $this->mdb2->escape($text); - } /** * Return associative array of values from two selected columns * for each row returned by the query. @@ -500,40 +497,27 @@ function fetch_assoc_array($sql, $key_column_name, $value_column_name, $args = n $rows = $this->fetch_rows($sql, $args); $result = array(); foreach ($rows as $row){ - $result[$row[$key_column_name]] = $row[$value_column_name]; + if( array_key_exists($key_column_name,$row) && array_key_exists($value_column_name,$row) ) { + $result[$row[$key_column_name]] = $row[$value_column_name]; + } else { + throw new DatabaseException("Columns $key_column_name or $value_column_name doesn't exists in result of query: $sql in fetch_assoc_array() database method."); + } } return $result; } // fetch_assoc_array() - /** - * Execute the specified query, fetch the value from the first column of - * the first row of the result set and then frees - * the result set. - * - * @param string $query the SELECT query statement to be executed. - * @param string $type optional argument that specifies the expected - * datatype of the result set field, so that an eventual - * conversion may be performed. The default datatype is - * text, meaning that no conversion is performed - * @param mixed $colnum the column number (or name) to fetch - * - * @return mixed MDB2_OK or field value on success, a MDB2 error on failure - * - * @access public - */ + public function get_encoding() { - function queryOne($query) - { - $result = $this->mdb2->query($query,null); - if (!MDB2::isResultCommon($result)) { - return $result; - } + return $this->_encoding; - $one = $result->fetchOne(0); - $result->free(); - return $one; - } + } // get_encoding() + + public function get_collate() { + + return $this->get_encoding().'_general_ci'; + + } // get_collate() -} +} // of Database class ?> diff --git a/engine/include/database/MDB2DatabaseEngine.php b/engine/include/database/MDB2DatabaseEngine.php index 48bd3c56..04dcd0c4 100644 --- a/engine/include/database/MDB2DatabaseEngine.php +++ b/engine/include/database/MDB2DatabaseEngine.php @@ -33,13 +33,6 @@ public function __construct($dsn) { } $this->mdb2->loadModule('Extended'); $this->mdb2->query("SET SESSION query_cache_type = ON"); - // hint for default using '0000-00-00' datetime field in tasks table :o( - $this->mdb2->query("SET @old_sql_mode := @@sql_mode"); - $this->mdb2->query("SET @new_sql_mode := @old_sql_mode"); - $this->mdb2->query("SET @new_sql_mode := TRIM(BOTH ',' FROM REPLACE(CONCAT(',',@new_sql_mode,','),',NO_ZERO_DATE,' ,','))"); - $this->mdb2->query("SET @new_sql_mode := TRIM(BOTH ',' FROM REPLACE(CONCAT(',',@new_sql_mode,','),',NO_ZERO_IN_DATE,',','))"); - $this->mdb2->query("SET @@sql_mode := @new_sql_mode;"); - } // __construct() public function prepareAndExecute($sql,$args=null) { diff --git a/engine/include/diagnostics/CPageAjaxDiagnostic.php b/engine/include/diagnostics/CPageAjaxDiagnostic.php index b3b94ec1..8a0910b9 100644 --- a/engine/include/diagnostics/CPageAjaxDiagnostic.php +++ b/engine/include/diagnostics/CPageAjaxDiagnostic.php @@ -2,7 +2,7 @@ class PageAjaxDiagnostic{ static function findAjaxUsage($file_keywords){ - $js_folder = Config::Config()->get_path_www() . "/js"; + $js_folder = Config::Cfg()->get_path_www() . "/js"; $files = scandir($js_folder); $regex_pattern = "/doAjax(.+|)[(]('|\")([^'\"]+)('|\")/"; $ajax_list = array(); @@ -41,7 +41,7 @@ static function findAjaxUsage($file_keywords){ } private static function getAjaxUsedOnPages($ajaxClassName){ - $filename = Config::Config()->get_path_engine() . "/ajax/" . strtolower($ajaxClassName) . ".php"; + $filename = Config::Cfg()->get_path_engine() . "/ajax/" . strtolower($ajaxClassName) . ".php"; if ( file_exists($filename) ){ require_once($filename); $p = new $ajaxClassName(); @@ -52,7 +52,7 @@ private static function getAjaxUsedOnPages($ajaxClassName){ } private function getAjaxAccessInfo($ajax_list){ - $validatorAjax = new PageAccessValidator(Config::Config()->get_path_engine(), "ajax"); + $validatorAjax = new PageAccessValidator(Config::Cfg()->get_path_engine(), "ajax"); $validatorAjax->process(); $ajax_access = $validatorAjax->items; @@ -166,7 +166,7 @@ private function hasAccessConflict($ajax){ */ private function getPageAccessInfoByFilename(){ - $validatorPage = new PageAccessValidator(Config::Config()->get_path_engine(), "page"); + $validatorPage = new PageAccessValidator(Config::Cfg()->get_path_engine(), "page"); $validatorPage->process(); $pages = $validatorPage->items; $pages_ordered = array(); diff --git a/engine/include/exceptions/BacktraceService.php b/engine/include/exceptions/BacktraceService.php new file mode 100644 index 00000000..366c5475 --- /dev/null +++ b/engine/include/exceptions/BacktraceService.php @@ -0,0 +1,90 @@ +0) { + array_pop($trace); + $removeLevels--; + } + return $trace; + + } // getBacktrace + + static private function formatCLITraceStr($traceArray) { + + $result = ""; + $index = count($traceArray)-1; + while($index>=0) { + //foreach($traceArray as $item) { + $item = $traceArray[$index--]; + $result .= ' ' + .(isset($item['file']) ? $item['file'] : '') + .' ' + .(isset($item['line']) ? $item['line'] : '') + .' calling ' . $item['function'] . '()' + . "\n"; + } + return $result; + + } // formatCLITraceStr + + static private function formatHTMLTraceStr($traceArray) { + + $result = '
    ' . "\n"; + $index = count($traceArray)-1; + while($index>=0) { + //foreach($traceArray as $item) { + $item = $traceArray[$index--]; + $result .= '
  1. ' + . (isset($item['file']) ? $item['file'] : '') + . ' ' + . (isset($item['line']) ? $item['line'] : '') + . ' calling ' . $item['function'] . '()' + . "
  2. \n"; + } + $result .= '
' . "\n"; + + return $result; + + } // formatHTMLTraceStr + + static public function formatTraceStr($traceArray) { + + if(php_sapi_name() == 'cli') { + return self::formatCLITraceStr($traceArray); + } else { + return self::formatHTMLTraceStr($traceArray); + } + + } // formatTraceStr() + + static public function formatTraceLogStr($traceArray) { + + $items = array(); + $index = count($traceArray)-1; + while($index>=0) { + //foreach($traceArray as $item) { + $item = $traceArray[$index--]; + $items[] = (isset($item['file']) ? $item['file'] : '') . ' ' + . (isset($item['line']) ? $item['line'] : '') + . ' calling ' . $item['function'] . '()'; + } + return join(' | ', $items); + + } // formatTraceLogStr() + +} // BacktraceService class + +?> + diff --git a/engine/include/exceptions/ErrorService.php b/engine/include/exceptions/ErrorService.php new file mode 100644 index 00000000..0d40dc76 --- /dev/null +++ b/engine/include/exceptions/ErrorService.php @@ -0,0 +1,207 @@ + 'ERROR', + E_WARNING => 'WARNING', + E_PARSE => 'PARSE', + E_NOTICE => 'NOTICE', + E_CORE_ERROR => 'CORE_ERROR', + E_CORE_WARNING => 'CORE_WARNING', + E_COMPILE_ERROR => 'COMPILE_ERROR', + E_COMPILE_WARNING => 'COMPILE_WARNING', + E_USER_ERROR => 'USER_ERROR', + E_USER_WARNING => 'USER_WARNING', + E_USER_NOTICE => 'USER_NOTICE', + E_STRICT => 'STRICT', + E_RECOVERABLE_ERROR => 'RECOVERABLE_ERROR', + E_DEPRECATED => 'DEPRECATED', + E_USER_DEPRECATED => 'USER_DEPRECATED', + ]; + + static private function getLevelStr($level) { + + $result = "UNKNOWN ERROR"; + if(array_key_exists($level,self::severities)) { + $result = self::severities[$level]; + } + return $result; + + } // getLevelStr() + + static private function errorMsgCLIStr($level,$message,$file,$line) { + + $msg = self::getLevelStr($level) + . ' \'' . $message . '\' at ' + . $file + . ' ' . $line . ' Trace: '."\n" + . BacktraceService::formatTraceStr(BacktraceService::getBacktrace(4)); + return $msg; + + } // errorMsgCLIStr() + + static private function errorMsgHTMLStr($level,$message,$file,$line) { + + $msg = '

' . "\n" + . self::getLevelStr($level) . ' \'' . $message . '\' at ' . $file . ' ' . $line . '
Trace :'. "\n"; + $msg .= BacktraceService::formatTraceStr(BacktraceService::getBacktrace(4)); + $msg .= '

'."\n"; + return $msg; + + } // errorMsgHTMLStr() + + static private function errorMsgLogStr($level,$message,$file,$line) { + + $msg = self::getLevelStr($level) + . ' \'' . $message . '\' at ' + . $file + . ' ' . $line . ' Trace: ' + . BacktraceService::formatTraceLogStr(BacktraceService::getBacktrace(3)); + return $msg; + + } // errorMsgLogStr() + + static private function errorMsgStr($level,$message,$file,$line) { + + if(php_sapi_name() == 'cli') { + return self::errorMsgCLIStr($level,$message,$file,$line); + } else { + return self::errorMsgHTMLStr($level,$message,$file,$line); + } + + } // errorMsgStr() + + static private function throwErrorException($level,$message,$file,$line) { + + //$text = "[".$level."] ".$message." in ".$file.":".$line; + //throw new ErrorException($text, 0, $level, $file, $line); + + $message = self::getLevelStr($level)." : ".$message; + $e = new Exception($message, 0); + // Just remove the current 2 points from the trace + $reflection = new ReflectionProperty(get_class($e), 'trace'); + $reflection->setAccessible(true); + $trace = $reflection->getValue($e); + array_shift($trace); + array_shift($trace); + $reflection->setValue($e, $trace); + + $reflection = new ReflectionProperty(get_class($e), 'file'); + $reflection->setAccessible(true); + $reflection->setValue($e, $file); + $reflection = new ReflectionProperty(get_class($e), 'line'); + $reflection->setAccessible(true); + $reflection->setValue($e, $line); + + throw($e); + + } // throwErrorException + + static public function errorHandler($level, $message, $file = ’’, $line = 0) { + // mask errors on error_reporting() settings + // here we have them all + $systemErrorReporting = error_reporting(); + if( ($systemErrorReporting & $level) == 0 ) { + // this error level is masked by system settings + UncaughtExceptionService::errorClearLast(); + return; + } + + // notice, warnings, strict print only if display_errors = 1 + // and continue running program + switch($level) { + case E_WARNING : + case E_USER_WARNING : + case E_STRICT : + case E_NOTICE : + case E_USER_NOTICE : + case E_CORE_WARNING : + case E_COMPILE_WARNING : + // log all to logfile + if(ini_get('log_errors')){ + error_log(self::errorMsgLogStr($level,$message,$file,$line)); + } + if(ini_get('display_errors')){ + print(self::errorMsgStr($level,$message,$file,$line)); + } else { + // none information in this case + } + return; + break; + default : // fatal errors + // exception should do logfile logging + // call exception - no return + self::throwErrorException($level,$message,$file,$line); + break; + } + + } // errorHandler() + + static public function shutdownFunction() { + + // returns null or array( "type"=>, "message"=>, "file"=>, "line"=> ) + // if earlier inforexInitialExceptionHandler was called, there not + // will be reported twice + $error = UncaughtExceptionService::errorGetLast(); + if ($error !== null) { + // dummy message if not errors displayed by system + if (!ini_get("display_errors")) { + UncaughtExceptionService::dummyMessage4User(); + } else { + // no action - system default + } + } + + } // shutdownFunction() + + // fatal error generator for testing purposes + // to generate fatal error - memory exhausted write + // self::throwFatalError(); + public static function throwFatalError() { + + // This method generate limit exhausted memory consumption + // PHP Fatal error: Allowed memory size of ... bytes exhausted + // + $bigCount = self::memoryLimitAsBytes() / 8; + $bigStr = str_repeat( "Hello|", $bigCount ); + $bigArray = explode( '|', $bigStr ); + $deadBuffer = array(); + foreach( $bigArray as $key => $item ){ + $deadBuffer[] = $item; + } + return $deadBuffer; + + } // throwFatalError + + private static function limitStrToBytes($limitStr) { + + switch(strtolower(substr($limitStr,-1))) { + case 'g': + return (int)$limitStr*1073741824; + case 'm': + return (int)$limitStr*1048576; + case 'k': + return (int)$limitStr*1024; + default: + return (int)$limitStr; + } + + } // limitStrToBytes() + + private static function memoryLimitAsBytes() { + + $limit = ini_get("memory_limit"); + return self::limitStrToBytes($limit); + + } // memoryLimitAsBytes + +} // class ErrorService + +?> diff --git a/engine/include/exceptions/UncaughtExceptionService.php b/engine/include/exceptions/UncaughtExceptionService.php new file mode 100644 index 00000000..ffe00bdb --- /dev/null +++ b/engine/include/exceptions/UncaughtExceptionService.php @@ -0,0 +1,122 @@ +'; + $H1Open='

'; $H1Close='

'; + print("

500 Internal Server Error


\n"); + } + $NL .= "\n"; + + print("An internal server error has been occurred.".$NL); + print("Please try again later.".$NL); + + } // dummyMessage4User + + static private function exceptionMsgCLIStr(Exception $e) { + + $msg = "Uncaught exception: ".$e->getMessage()."\n" + ." in file ".$e->getFile()." on line ".$e->getLine()."\n" + .$e->getTraceAsString()."\n"; + return $msg; + + } // exceptionMsgCLIStr() + + static private function exceptionMsgHTMLStr(Exception $e) { + + $msg = "Uncaught exception: ".$e->getMessage()."\n" + ."
 in file ".$e->getFile()." on line ".$e->getLine()."
\n" + ."
".$e->getTraceAsString()."
\n"; + return $msg; + + } // exceptionMsgHTMLStr() + + static private function exceptionMessage(Exception $e) { + + if(php_sapi_name() == 'cli') { + print(self::exceptionMsgCLIStr($e)); + } else { + // there actions for browser environment only + http_response_code(500); + print(self::exceptionMsgHTMLStr($e)); + } + + } // exceptionMessage() + + static public function UncaughtException(Exception $e) { + + if(ini_get('display_errors')){ + self::exceptionMessage($e); + } else { + self::dummyMessage4User(); + } + + // logging information to logfile always, if not disallow + if(ini_get('log_errors')){ + error_log("Uncaught exception: ".$e->getMessage()." in file ".$e->getFile()." on line ".$e->getLine()." Trace:".$e->getTraceAsString(),0); + } + + // serviced errors shouldn't be processed again + self::errorClearLast(); + + } // UncaughtException() + + +} // UncaughtExceptionService class + +?> diff --git a/engine/include/exceptions/ajax/GeneralAjaxException.php b/engine/include/exceptions/ajax/GeneralAjaxException.php new file mode 100644 index 00000000..19b9bd1d --- /dev/null +++ b/engine/include/exceptions/ajax/GeneralAjaxException.php @@ -0,0 +1,7 @@ + diff --git a/engine/include/exceptions/config/ConfigException.php b/engine/include/exceptions/config/ConfigException.php new file mode 100644 index 00000000..16ea0614 --- /dev/null +++ b/engine/include/exceptions/config/ConfigException.php @@ -0,0 +1,7 @@ + diff --git a/engine/include/exceptions/include/CRequestException.php b/engine/include/exceptions/include/CRequestException.php new file mode 100644 index 00000000..970cc38d --- /dev/null +++ b/engine/include/exceptions/include/CRequestException.php @@ -0,0 +1,7 @@ + diff --git a/engine/include/export/CCclFactory.php b/engine/include/export/CclExportDocument.php similarity index 72% rename from engine/include/export/CCclFactory.php rename to engine/include/export/CclExportDocument.php index 130412b7..48bef54f 100644 --- a/engine/include/export/CCclFactory.php +++ b/engine/include/export/CclExportDocument.php @@ -6,24 +6,32 @@ * See LICENCE */ -class CclFactory{ +class CclExportDocument extends CclDocument { /** * $report --- tablica asocjacyjna z atrybutami dokumentu (jak z tabeli reports) * $tokens --- tablica asocjacyjna z wartościami 'from', 'to' i 'eos' * $tags --- * function creates ccl document using 'eos' token attributes to match end of sentence - * see: createFromReportAndTokensSentence + * see: createFromReportAndTokensSentence, was createFromReportAndTokens() */ - function createFromReportAndTokens(&$report, &$tokens, &$tags){ - $fileName = str_pad($report['id'],8,'0',STR_PAD_LEFT); + public function __construct(&$report, &$tokens, &$tags){ + + $reportIdStr = isset($report['id']) ? $report['id'] : ''; + $reportContent = isset($report['content']) ? $report['content'] :''; + + $fileName = str_pad($reportIdStr,8,'0',STR_PAD_LEFT); - $ccl = new CclDocument(); - $ccl->setFileName($fileName); - $ccl->setSubcorpus(preg_replace("/[^\p{L}|\p{N}]+/u","_",$report['name'])); - $ccl->setReport($report); + $this->setFileName($fileName); + $this->setSubcorpus( + // SW ?? there are not 'name' column in DB table reports + isset($report['name']) + ? preg_replace("/[^\p{L}|\p{N}]+/u","_",$report['name']) + : "" + ); + $this->setReport($report); - $chunkList = explode('<\\chunk>', $report['content']); + $chunkList = explode('<\\chunk>', $reportContent); $from = 0; $to = 0; @@ -34,7 +42,10 @@ function createFromReportAndTokens(&$report, &$tokens, &$tags){ $chunk = str_replace(">","> ",$chunk); preg_match_all($pattern, $chunk, $matches); $type = "p"; - if (is_array($matches) && array_key_exists(1, $matches)) + if (is_array($matches) + && array_key_exists(1, $matches) + && array_key_exists(0,$matches[1]) + ) $type = $matches[1][0]; $tmpStr = trim(preg_replace("/\s\s+/"," ",custom_html_entity_decode(strip_tags($chunk)))); $tmpStr2 = preg_replace("/\n+|\r+|\s+/","",$tmpStr); @@ -49,7 +60,7 @@ function createFromReportAndTokens(&$report, &$tokens, &$tags){ $from = $to+1; } - $htmlStr = new HtmlStr2(strip_tags($report['content']), false); + $htmlStr = new HtmlStr2(strip_tags($reportContent), false); // Podziel tokeny miedzy chunkami $tokenIndex = 0; @@ -93,7 +104,7 @@ function createFromReportAndTokens(&$report, &$tokens, &$tags){ } $s->addToken($t); - $ccl->addToken($t); + $this->addToken($t); if ( $token['eos'] ){ $c->addSentence($s); $s = new CclSentence(); @@ -108,37 +119,36 @@ function createFromReportAndTokens(&$report, &$tokens, &$tags){ else $sentenceIndex--; } - $ccl->addChunk($c); + $this->addChunk($c); } - return $ccl; - } + } // __construct() - function setAnnotationLemmas(&$ccl, &$annotation_lemmas){ + protected function setAnnotationLemmas($annotation_lemmas){ if (empty($annotation_lemmas)){ return false; } foreach($annotation_lemmas as $lemma){ - $ccl->setAnnotationLemma($lemma); + $this->setAnnotationLemma($lemma); } } - function setAnnotationProperties(&$ccl, &$annotation_properties){ + protected function setAnnotationProperties($annotation_properties){ if (empty($annotation_properties)){ return false; } foreach($annotation_properties as $property){ - $ccl->setAnnotationProperty($property); + $this->setAnnotationProperty($property); } } /** * */ - function setAnnotationsAndRelations(&$ccl, &$annotations, &$relations){ + protected function setAnnotationsAndRelations(&$annotations, &$relations){ if (empty($annotations)) return false; $annotationsById = array(); $continuousAnnotationIds = array(); @@ -157,7 +167,7 @@ function setAnnotationsAndRelations(&$ccl, &$annotations, &$relations){ foreach ($annotations as &$annotation){ if ( !in_array($annotation['id'], $continuousAnnotationIds)){ - $ccl->setAnnotation($annotation); + $this->setAnnotation($annotation); } else { $continuousAnnotations[$annotation['id']] =& $annotation; } @@ -169,7 +179,7 @@ function setAnnotationsAndRelations(&$ccl, &$annotations, &$relations){ $target_id = $cRelation['target_id']; if (array_key_exists($source_id, $annotationsById) && array_key_exists($target_id, $annotationsById)){ - $ccl->setContinuousAnnotation2( + $this->setContinuousAnnotation2( $continuousAnnotations[$source_id], $continuousAnnotations[$target_id]); } else if (array_key_exists($source_id, $annotationsById) || @@ -179,7 +189,7 @@ function setAnnotationsAndRelations(&$ccl, &$annotations, &$relations){ $e->setFunctionName("setAnnotationsAndRelations"); $e->addObject("relation", $cRelation); $e->addComment("008 no source or target annotation in a continuous relation"); - $ccl->addError($e); + $this->addError($e); } } @@ -188,7 +198,7 @@ function setAnnotationsAndRelations(&$ccl, &$annotations, &$relations){ $target_id = $nRelation['target_id']; if (array_key_exists($source_id, $annotationsById) && array_key_exists($target_id, $annotationsById)){ - $ccl->setRelation( + $this->setRelation( $annotationsById[$nRelation['source_id']], $annotationsById[$nRelation['target_id']], $nRelation); @@ -198,10 +208,21 @@ function setAnnotationsAndRelations(&$ccl, &$annotations, &$relations){ $e->setFunctionName("setAnnotationsAndRelations"); $e->addObject("relation", $nRelation); $e->addComment("009 no source or target annotation in a normal relation"); - $ccl->addError($e); + $this->addError($e); } } return true; } -} + public function setCclProperties(&$annotations, &$relations, $lemmas, $attributes ) { + + $this->setAnnotationsAndRelations($annotations, $relations); + // Lemmas will be added only if annotations are too + if(is_array($annotations) && (count($annotations)>0)) { + $this->setAnnotationLemmas($lemmas); + } + $this->setAnnotationProperties($attributes); + + } // setCclProperties() + +} // CclExportDocument class diff --git a/engine/include/export/ConllAndJsonFactory.php b/engine/include/export/ConllAndJsonFactory.php index 68c9a4cf..6cbd7038 100644 --- a/engine/include/export/ConllAndJsonFactory.php +++ b/engine/include/export/ConllAndJsonFactory.php @@ -1,10 +1,44 @@ => [ 'idx'=>.., 'lemma'=>.. ] + **/ + protected function makeLemmaCache(array $lemma) { + + $lemmaCache = array(); + for($i=0;$i$i, + 'lemma'=> isset($lemma[$i]['lemma']) + ? $lemma[$i]['lemma'] + : null // lemma record with no 'lemma' field + ); + } + } + return $lemmaCache; + + } // makeLemmaCache() + + protected function makeConllAndJsonExportData($ccl, $tokens, $relations, $annotations, $tokens_ids, $annotations_by_id, $lemmas) { + + // create index for $lemmas + $lemmas_by_annotation_id = $this->makeLemmaCache($lemmas); + // add only lemmas pointed by extractor to proper annotations + foreach($annotations as &$ann) { + if(array_key_exists($ann['id'],$lemmas_by_annotation_id)) { + $ann['lemma']=$lemmas_by_annotation_id[$ann['id']]['lemma']; + } + } + /** * Create a cache for 'token from' to boost processing */ @@ -90,7 +124,7 @@ function exportToConllAndJson($file_path_without_ext, $ccl, $tokens, $relations, $json_sentence = []; $id = 0; foreach ($sentence->tokens as $token) { - $original_id = $tokens_ids[$it++]; + $original_id = isset($tokens_ids[$it]) ? $tokens_ids[$it++] : null; $ann_tag = []; $ann_id = []; $rel_id = []; @@ -102,7 +136,7 @@ function exportToConllAndJson($file_path_without_ext, $ccl, $tokens, $relations, $iob = $annotations_from_cache["iob"]; $annotation = $annotations_by_id[$annotations_from_cache_id]; - $ann_tag[] = $iob . $annotation['name']; + $ann_tag[] = $iob . $annotation['type']; $ann_id[] = $annotation['id']; if (array_key_exists($annotation['id'], $relations_cache)) { @@ -117,11 +151,12 @@ function exportToConllAndJson($file_path_without_ext, $ccl, $tokens, $relations, } } $token_id = $id++; + $ctag = isset($token->lexemes[0]->ctag) ? $token->lexemes[0]->ctag :''; $json_sentence[] = array( "order_id" => $token->id, "token_id" => $token_id, "orth" => $token->orth, - "ctag" => $token->lexemes[0]->ctag, + "ctag" => $ctag, "from" => $token->from, "to" => $token->to, "annotations" => $ann_id, @@ -138,7 +173,7 @@ function exportToConllAndJson($file_path_without_ext, $ccl, $tokens, $relations, $array_to_check += ["_"]; } } - $conll .= $token->id . "\t" . $token_id . "\t" . $token->orth . "\t" . $token->lexemes[0]->ctag . "\t" . $token->from . "\t" . + $conll .= $token->id . "\t" . $token_id . "\t" . $token->orth . "\t" . $ctag . "\t" . $token->from . "\t" . $token->to . "\t" . join(":", $ann_tag) . "\t" . join(":", $ann_id) . "\t" . join(":", $rel_id) . "\t" . join(":", $rel_target_id) . "\n"; @@ -149,13 +184,17 @@ function exportToConllAndJson($file_path_without_ext, $ccl, $tokens, $relations, $json_builder["chunks"][] = $json_sentences; } - $handle = fopen($file_path_without_ext . ".conll", "w"); - fwrite($handle, $conll); - fclose($handle); + return array($conll,$json_builder); + + } // makeConllAndJsonExportData() + + public function exportToConllAndJson($file_path_without_ext, $ccl, $tokens, $relations, $annotations, $tokens_ids, $annotations_by_id, $lemmas) + { + list($conll,$json_builder) = $this->makeConllAndJsonExportData($ccl, $tokens, $relations, $annotations, $tokens_ids, $annotations_by_id, $lemmas); + $fw = new FileWriter(); + $fw->writeTextToFile($file_path_without_ext . ".conll",$conll); + $fw->writeJSONToFile($file_path_without_ext . ".json",$json_builder); - $handle = fopen($file_path_without_ext . ".json", "w"); - fwrite($handle, json_encode($json_builder, JSON_PRETTY_PRINT + JSON_UNESCAPED_UNICODE)); - fclose($handle); - } + } // exportToConllAndJson() -} \ No newline at end of file +} // ConllAndJsonFactory class diff --git a/engine/include/export/CorpusExporter.php b/engine/include/export/CorpusExporter.php index 953ad8dd..3224dd67 100644 --- a/engine/include/export/CorpusExporter.php +++ b/engine/include/export/CorpusExporter.php @@ -9,7 +9,7 @@ * */ class CorpusExporter{ - private $export_errors = array(); + protected $export_errors = array(); /** * Returns array given as param, without all items with value null @@ -32,6 +32,24 @@ public static function arrayRemoveNullElements(array $arr) { return $arr; } // arrayRemoveNullElements() + /** + * Parameter array should be list of subarrays with field => + * We remove all fileds with =='lemma' + * + * @param $ann - list of associative arrays + * + * @returns - array given w/o 'lemma' fields + */ + private function RemoveLemmaFieldFromAnnotationsList(array $anns) { + + foreach($anns as &$ann) { + if(array_key_exists('lemma',$ann)) + unset($ann['lemma']); + } + return $anns; + + } // RemoveLemmaFieldFromAnnotationsList() + /** * Funkcja parsuje opis ekstraktora danych * @@ -61,7 +79,11 @@ public static function arrayRemoveNullElements(array $arr) { */ protected function parse_extractor($description){ $extractors = array(); - $parts = explode(":", $description); + try { + $parts = explode(":", $description); + } catch(Exception $ex){ + throw new Exception("Niepoprawny opis ekstraktora "); + } // catch() if ( count($parts) !== 2 ){ throw new Exception("Niepoprawny opis ekstraktora " . $description); } @@ -143,6 +165,8 @@ protected function parse_extractor($description){ // $params -- annotations_set_ids, $stages $annotations = DbAnnotation::getReportAnnotations($report_id, $params["user_ids"], $params["annotation_set_ids"], $params["annotation_subset_ids"], null, $params["stages"]); + // we don't want lemma field in full annotation records + $annotations = $this->RemoveLemmaFieldFromAnnotationsList($annotations); if ( is_array($annotations) ) { $elements['annotations'] = array_merge($elements['annotations'], $annotations); } @@ -311,7 +335,8 @@ private function log_error($file_name, $line_no, $report_id, $message, $error_ty break; //Problem z utworzeniem CCL case 2: - $this->export_errors[$error_type]['details']['names'][$error_params['name']] = 1; + if(isset($error_params['name'])) + $this->export_errors[$error_type]['details']['names'][$error_params['name']] = 1; $this->export_errors[$error_type]['details']['error'][$error_params['error']] = 1; break; //Brak anotacji źródłowej dla relacji @@ -355,7 +380,7 @@ private function makeAssocArray($arr, $key, $disamb_only=false){ return $ret; } - private function getReportTagsByTokens($report_id, $tokens_ids, $disamb_only=true, $tagging='tagger'){ + protected function getReportTagsByTokens($report_id, $tokens_ids, $disamb_only=true, $tagging='tagger'){ $tags = array(); $tags_by_tokens = array(); @@ -447,6 +472,269 @@ private function getReportTagsByTokens($report_id, $tokens_ids, $disamb_only=tru return $tags_by_tokens; } + protected function getFlagsByReportId($report_id) { + + return DbReportFlag::getReportFlags($report_id); + + } // getFlagsByReportId() + + protected function getTokenByReportId($report_id){ + + return DbToken::getTokenByReportId($report_id, null, true); + + } // getTokenByReportId() + + protected function getReportById($report_id){ + + return DbReport::getReportById($report_id); + + } // getReportById() + + protected function getReportExtById($report_id){ + + return DbReport::getReportExtById($report_id); + + } // getReportExtById() + + protected function getFormatName($format_id) { + + return DbReport::formatName($format_id); + + } // getFormatName() + + protected function exportReportContent($report,$file_path_without_ext) { + + try { + // getHtmlStr() need $report['format'] field, which isn't + // exists in `reports` DB now. We must create it from + // $reports['format_id']. Its not elegant here, but works... + if(!isset($report['format'])){ + $report['format'] = + isset($report['format_id']) && $report['format_id'] + ? $this->getFormatName($report['format_id']) + : 'xml' ; // default for default format_id=1 + } + $html = ReportContent::getHtmlStr($report); + } catch(Exception $ex){ + $errorMsg = "Problem z eksportem zawartości HTML dokumentu"; + $exceptionMsg = $ex->getMessage(); + $error_params = array( + 'message' => $errorMsg, + 'error' => $exceptionMsg + ); + $this->log_error(__FILE__, __LINE__, $report["id"], + $errorMsg.": ".$exceptionMsg, 8, $error_params); + return False; + } // catch() + $content = $html->getContent(); + file_put_contents($file_path_without_ext .".txt", $content); + return True; + + } // exportReportContent() + + protected function updateLists($flags,$reportFileName,&$lists) { + + /* Przypisanie dokumentu do list */ + foreach ( $lists as $ix=>$list){ + foreach ( $list['flags'] as $flag){ + $flag_name = $flag["flag_name"]; + $flag_ids = $flag["flag_ids"]; + if ( isset($flags[$flag_name]) && in_array($flags[$flag_name], $flag_ids) ){ + $lists[$ix]["document_names"][$reportFileName.".xml"] = 1; + } + } + } + // returns changes in $lists array from params + + } // updateLists() + + protected function createIniFile($report,$subcorpora,$file_path_without_ext) { + + $ext = $this->getReportExtById($report["id"]); + + $basic = array("id", "date", "title", "source", "author", "tokenization", "subcorpus"); + $lines = array(); + $lines[] = "[document]"; + $report["subcorpus"] = isset($subcorpora[$report['subcorpus_id']]) ? $subcorpora[$report['subcorpus_id']] : ""; + + foreach ($basic as $name){ + $lines[] = sprintf("%s = %s", $name, $report[$name]); + } + if ( is_array($ext) && (count($ext) > 0) ){ + $lines[] = ""; + $lines[] = "[metadata]"; + foreach ($ext as $key=>$val){ + if ($key != "id"){ + $key = preg_replace("/[^\p{L}|\p{N}]+/u", "_", $key); + $lines[] = sprintf("%s = %s", $key, $val); + } + } + } + file_put_contents($file_path_without_ext.".ini", implode("\n", $lines)); + + } // createIniFile() + + protected function checkIfAnnotationForLemmaExists($report_id,$lemmas,$annotations_by_id) { + + $allLemmasCorrect = True; + foreach ($lemmas as $an){ + $anid = intval($an['id']); + if ( !isset($annotations_by_id[$anid]) ){ + $error_params = array( + 'message' => "Brak warstwy anotacji dla lematu.", + 'group_id' => $an['group_id'], + 'lemma' => $an['name'] + ); + $this->log_error(__FILE__, __LINE__, $report_id, "brak anotacji $anid dla lematu ({$an["name"]}) -- brakuje warstwy anotacji?", 6, $error_params); + $allLemmasCorrect = False; + } + } + return $allLemmasCorrect; + + } // checkIfAnnotationForLemmaExists() + + protected function checkIfAnnotationForRelationExists($report_id,$relations,$annotations_by_id) { + /* Sprawdzenie, anotacji źródłowych i docelowych dla relacji */ + $allRelationsCorrect = True; + foreach ( $relations as $rel ){ + $source_id = $rel["source_id"]; + $target_id = $rel["target_id"]; + if ( !isset($annotations_by_id[$source_id]) ){ + $error_params = array( + 'message' => "Brak anotacji źródłowej dla relacji.", + 'source_id' => $source_id, + 'relation' => $rel["name"] + ); + $this->log_error(__FILE__, __LINE__, $report_id, "brak anotacji źródłowej o identyfikatorze $source_id ({$rel["name"]}) -- brakuje warstwy anotacji?", 4, $error_params); + $allRelationsCorrect = False; + } + if ( !isset($annotations_by_id[$target_id]) ){ + $error_params = array( + 'message' => "Brak anotacji docelowej dla relacji.", + 'target_id' => $target_id, + 'relation' => $rel["name"] + ); + $this->log_error(__FILE__, __LINE__, $report_id, "brak anotacji źródłowej o identyfikatorze $target_id ({$rel["name"]}) -- brakuje warsty anotacji?", 5, $error_params); + $allRelationsCorrect = False; + } + } + return $allRelationsCorrect; + + } // checkIfAnnotationForRelationExists() + + protected function sortUniqueAnnotationsById($report_id,$annotations) { + + /* Usunięcie zduplikowanych anotacji */ + $annotations_by_id = array(); + foreach ($annotations as $an){ + $anid = isset($an['id']) ? intval($an['id']) : 0; + if ( $anid > 0 ){ + $annotations_by_id[$anid] = $an; + } + else{ + $error_params = array( + 'message' => "Brak identyfikatora anotacji." + ); + $this->log_error(__FILE__, __LINE__, $report_id, "brak identyfikatora anotacji", 3, $error_params); + } + } + return $annotations_by_id; + + } // sortUniqueAnnotationsById() + + protected function dispatchElements($elements) { + + $annotations = array(); + $relations = array(); + $lemmas = array(); + $attributes = array(); + if ( isset($elements["annotations"]) && count($elements["annotations"]) ){ + $annotations = $elements["annotations"]; + } + if ( isset($elements["relations"]) && count($elements["relations"]) ){ + $relations = $elements["relations"]; + } + if ( isset($elements["lemmas"]) && count($elements["lemmas"]) ){ + $lemmas = $elements["lemmas"]; + } + + if ( isset($elements["attributes"]) && count($elements["attributes"]) ){ + $attributes = $elements["attributes"]; + } + return [$annotations,$relations,$lemmas,$attributes]; + + } // dispatchElements() + + protected function callCclCreator($report,$tokens,$tags_by_tokens) { + + $ccl = new CclExportDocument($report, $tokens, $tags_by_tokens); + return $ccl; + + } // callCclCreator() + + protected function generateCcl($report,$tokens,$tags_by_tokens) { + + try{ + $ccl = $this->callCclCreator($report, $tokens, $tags_by_tokens); + } + catch(Exception $ex){ + $error = $ex->getMessage(); + $error_params = array( + 'message' => "Problem z utworzeniem CCL", + 'error' => $error + ); + $this->log_error(__FILE__, __LINE__, $report["id"], "Problem z utworzeniem ccl: " . $error, 2, $error_params); + return False; // error is collected + } + return $ccl; // all ok + + } // generateCcl() + + protected function updateExtractorStats($extractorName,$extractor_stats,$extractor_elements) { + + // update $extractor_stats table, for index $extractorName + // with counter from $extractor_elements results + // Returns updated stats table + $name = $extractorName; + if ( !isset($extractor_stats[$name]) ){ + $extractor_stats[$name] = array(); + } + foreach ( $extractor_elements as $type=>$items ){ + if ( !isset($extractor_stats[$name][$type]) ){ + $extractor_stats[$name][$type] = count($items); + } else { + $extractor_stats[$name][$type] += count($items); + } + } + return $extractor_stats; + + } // updateExtractorStats() + + protected function runExtractor($flags,$report_id,$extractor,&$elements,&$extractor_stats) { + + // Wykonaj extraktor w zależności od ustalonej flagi + $func = $extractor["extractor"]; + $params = $extractor["params"]; + $flag_name = $extractor["flag_name"]; + $flag_ids = $extractor["flag_ids"]; + if ( isset($flags[$flag_name]) && in_array($flags[$flag_name], $flag_ids) ){ + $extractor_elements = array(); + foreach (array_keys($elements) as $key){ + $extractor_elements[$key] = array(); + } + + $func($report_id, $params, $extractor_elements); + + foreach (array_keys($extractor_elements) as $key){ + $elements[$key] = array_merge($elements[$key], $extractor_elements[$key]); + } + + // Zapisz statystyki + $extractor_stats = $this->updateExtractorStats($extractor["name"],$extractor_stats,$extractor_elements); + } // if flags is set + + } // runExtractorFunction() + /** * Eksport dokumentu o wskazanym identyfikatorze * @param $report_id Identyfikator dokumentu do eksportu @@ -456,190 +744,72 @@ private function getReportTagsByTokens($report_id, $tokens_ids, $disamb_only=tru * @param $tagging_method String tagging method from ['tagger', 'final', 'final_or_tagger', 'user:{id}'] */ protected function export_document($report_id, $extractors, $disamb_only, &$extractor_stats, &$lists, $output_folder, $subcorpora, $tagging_method){ - $flags = DbReportFlag::getReportFlags($report_id); + $flags = $this->getFlagsByReportId($report_id); $elements = array("annotations"=>array(), "relations"=>array(), "lemmas"=>array(), "attributes"=>array()); - // Wykonaj extraktor w zależności od ustalonej flagi + // Wykonaj extraktory w zależności od ustalonej flagi foreach ( $extractors as $extractor ){ - $func = $extractor["extractor"]; - $params = $extractor["params"]; - $flag_name = $extractor["flag_name"]; - $flag_ids = $extractor["flag_ids"]; - if ( isset($flags[$flag_name]) && in_array($flags[$flag_name], $flag_ids) ){ - $extractor_elements = array(); - foreach (array_keys($elements) as $key){ - $extractor_elements[$key] = array(); - } - $func($report_id, $params, $extractor_elements); - foreach (array_keys($extractor_elements) as $key){ - $elements[$key] = array_merge($elements[$key], $extractor_elements[$key]); - } - // Zapisz statystyki - $name = $extractor["name"]; - if ( !isset($extractor_stats[$name]) ){ - $extractor_stats[$name] = array(); - } - foreach ( $extractor_elements as $type=>$items ){ - if ( !isset($extractor_stats[$name][$type]) ){ - $extractor_stats[$name][$type] = count($items); - } - else{ - $extractor_stats[$name][$type] += count($items); - } - } - } + $this->runExtractor($flags,$report_id,$extractor,$elements,$extractor_stats); } - $tokens = DbToken::getTokenByReportId($report_id, null, true); + $tokens = $this->getTokenByReportId($report_id); $tokens_ids = array_column($tokens, 'token_id'); $tags_by_tokens = $this->getReportTagsByTokens($report_id, $tokens_ids, $disamb_only, $tagging_method); - $report = DbReport::getReportById($report_id); - try{ - $ccl = CclFactory::createFromReportAndTokens($report, $tokens, $tags_by_tokens); - } - catch(Exception $ex){ - $error = $ex->getMessage(); - $error_params = array( - 'message' => "Problem z utworzeniem CCL", - 'error' => $error - ); - $this->log_error(__FILE__, __LINE__, $report_id, "Problem z utworzeniem ccl: " . $error, 2, $error_params); - return; - } - $annotations = array(); - $relations = array(); - $lemmas = array(); - $attributes = array(); - if ( isset($elements["annotations"]) && count($elements["annotations"]) ){ - $annotations = $elements["annotations"]; - } - if ( isset($elements["relations"]) && count($elements["relations"]) ){ - $relations = $elements["relations"]; - } - if ( isset($elements["lemmas"]) && count($elements["lemmas"]) ){ - $lemmas = $elements["lemmas"]; - } + $report = $this->getReportById($report_id); - if ( isset($elements["attributes"]) && count($elements["attributes"]) ){ - $attributes = $elements["attributes"]; - } + $ccl = $this->generateCcl($report,$tokens,$tags_by_tokens); + if($ccl===False) { return; } + + list($annotations,$relations,$lemmas,$attributes) = $this->dispatchElements($elements); /* Usunięcie zduplikowanych anotacji */ - $annotations_by_id = array(); - foreach ($annotations as $an){ - $anid = intval($an['id']); - if ( $anid > 0 ){ - $annotations_by_id[$anid] = $an; - } - else{ - $error_params = array( - 'message' => "Brak identyfikatora anotacji." - ); - $this->log_error(__FILE__, __LINE__, $report_id, "brak identyfikatora anotacji", 3, $error_params); - } - } + $annotations_by_id = $this->sortUniqueAnnotationsById($report_id,$annotations); $annotations = array_values($annotations_by_id); /* Sprawdzenie, anotacji źródłowych i docelowych dla relacji */ - foreach ( $relations as $rel ){ - $source_id = $rel["source_id"]; - $target_id = $rel["target_id"]; - if ( !isset($annotations_by_id[$source_id]) ){ - $error_params = array( - 'message' => "Brak anotacji źródłowej dla relacji.", - 'source_id' => $source_id, - 'relation' => $rel["name"] - ); - $this->log_error(__FILE__, __LINE__, $report_id, "brak anotacji źródłowej o identyfikatorze $source_id ({$rel["name"]}) -- brakuje warstwy anotacji?", 4, $error_params); - } - if ( !isset($annotations_by_id[$target_id]) ){ - $error_params = array( - 'message' => "Brak anotacji docelowej dla relacji.", - 'target_id' => $target_id, - 'relation' => $rel["name"] - ); - $this->log_error(__FILE__, __LINE__, $report_id, "brak anotacji źródłowej o identyfikatorze $target_id ({$rel["name"]}) -- brakuje warsty anotacji?", 5, $error_params); - } - } + $this->checkIfAnnotationForRelationExists($report_id,$relations,$annotations_by_id); /* Sprawdzenie lematów */ - foreach ($lemmas as $an){ - $anid = intval($an['id']); - if ( !isset($annotations_by_id[$anid]) ){ - $error_params = array( - 'message' => "Brak warstwy anotacji dla lematu.", - 'group_id' => $an['group_id'], - 'lemma' => $an['name'] - ); - $this->log_error(__FILE__, __LINE__, $report_id, "brak anotacji $anid dla lematu ({$an["name"]}) -- brakuje warstwy anotacji?", 6, $error_params); - } - } + $this->checkIfAnnotationForLemmaExists($report_id,$lemmas,$annotations_by_id); $file_path_without_ext = $output_folder . "/" . $ccl->getFileName(); /* Wygeneruj CONLL i JSON */ - ConllAndJsonFactory::exportToConllAndJson($file_path_without_ext, $ccl, $tokens, $relations, $annotations, $tokens_ids, $annotations_by_id); + (new ConllAndJsonFactory())->exportToConllAndJson($file_path_without_ext, $ccl, $tokens, $relations, $annotations, $tokens_ids, $annotations_by_id, $lemmas); /* Wygeneruj xml i rel.xml */ - CclFactory::setAnnotationsAndRelations($ccl, $annotations, $relations); - CclFactory::setAnnotationLemmas($ccl, $lemmas); - CclFactory::setAnnotationProperties($ccl, $attributes); - CclWriter::write($ccl, $output_folder . "/" . $ccl->getFileName() . ".xml", CclWriter::$CCL); - CclWriter::write($ccl, $output_folder . "/" . $ccl->getFileName() . ".rel.xml", CclWriter::$REL); + (new XmlFactory())->exportToXmlAndRelxml($file_path_without_ext,$ccl,$annotations,$relations,$lemmas,$attributes); /* Eksport metadanych */ - $report = DbReport::getReportById($report_id); - $ext = DbReport::getReportExtById($report_id); + $this->createIniFile($report,$subcorpora,$file_path_without_ext); - $basic = array("id", "date", "title", "source", "author", "tokenization", "subcorpus"); - $lines = array(); - $lines[] = "[document]"; - $report["subcorpus"] = $subcorpora[$report['subcorpus_id']]; + /* Przypisanie dokumentu do list */ + $this->updateLists($flags,$ccl->getFileName(),$lists); + $this->exportReportContent($report,$file_path_without_ext); - foreach ($basic as $name){ - $lines[] = sprintf("%s = %s", $name, $report[$name]); - } - if ( count($ext) > 0 ){ - $lines[] = ""; - $lines[] = "[metadata]"; - foreach ($ext as $key=>$val){ - if ($key != "id"){ - $key = preg_replace("/[^\p{L}|\p{N}]+/u", "_", $key); - $lines[] = sprintf("%s = %s", $key, $val); - } - } - } - file_put_contents($output_folder . "/" . $ccl->getFileName() . ".ini", implode("\n", $lines)); + } // export_document() - /* Przypisanie dokumentu do list */ - foreach ( $lists as $ix=>$list){ - foreach ( $list['flags'] as $flag){ - $flag_name = $flag["flag_name"]; - $flag_ids = $flag["flag_ids"]; - if ( isset($flags[$flag_name]) && in_array($flags[$flag_name], $flag_ids) ){ - $lists[$ix]["document_names"][$ccl->getFileName() . ".xml"] = 1; - } - } - } - try { - $html = ReportContent::getHtmlStr($report); - } catch(Exception $ex){ - $errorMsg = "Problem z eksportem zawartości HTML dokumentu"; - $exceptionMsg = $ex->getMessage(); - $error_params = array( - 'message' => $errorMsg, - 'error' => $exceptionMsg - ); - $this->log_error(__FILE__, __LINE__, $report_id, - $errorMsg.": ".$exceptionMsg, 8, $error_params); - return; - } // catch() - $content = $html->getContent(); - file_put_contents($output_folder . "/" . $ccl->getFileName() . ".txt", $content); + protected function getSubcorporaList() { - } + /* Przygotuj listę podkorpusów w postaci tablicy id=>nazwa*/ + $subcorpora_assoc = DbCorpus::getSubcorpora(); + $subcorpora = array(); + foreach ( $subcorpora_assoc as $sub ){ + $subcorpora[$sub['subcorpus_id']] = $sub['name']; + } + return $subcorpora; + + } // getSubcorporaList() + + protected function writeConsoleMessage($msg) { + + $isCLI = (php_sapi_name() == 'cli'); + if($isCLI) + echo($msg); + + } // writeConsoleMessage() /** * Wykonuje eksport korpusu zgodnie z określonymi parametrami (selektory, ekstraktory i indeksy). @@ -656,13 +826,8 @@ public function exportToCcl($output_folder, $selectors_description, $extractors_ mkdir("$output_folder/documents", 0777, true); } - /* Przygotuj listę podkorpusów w postaci tablicy id=>nazwa*/ - $subcorpora_assoc = DbCorpus::getSubcorpora(); - $subcorpora = array(); - foreach ( $subcorpora_assoc as $sub ){ - $subcorpora[$sub['subcorpus_id']] = $sub['name']; - } + $subcorpora = $this->getSubcorporaList(); $extractors = array(); foreach ( $extractors_description as $extractor ){ @@ -682,7 +847,7 @@ public function exportToCcl($output_folder, $selectors_description, $extractors_ } $document_ids = array_keys($document_ids); - echo "Liczba dokumentów do eksportu: " . count($document_ids) . "\n"; + $this->writeConsoleMessage("Liczba dokumentów do eksportu: " . count($document_ids) . "\n"); $extractor_stats = array(); $number_of_docs = count($document_ids); @@ -696,11 +861,11 @@ public function exportToCcl($output_folder, $selectors_description, $extractors_ if($percent_done > $progress){ $progress = $percent_done; DbExport::updateExportProgress($export_id, $progress); - echo intval($progress) . "%" . "\n"; + $this->writeConsoleMessage(intval($progress) . "%" . "\n"); } } foreach ($lists as $list){ - echo sprintf("%4d %s\n", count(array_keys($list["document_names"])), $list["name"]); + $this->writeConsoleMessage(sprintf("%4d %s\n", count(array_keys($list["document_names"])), $list["name"])); $lines = array(); foreach ( array_keys($list["document_names"]) as $document_name ){ $lines[] = "./documents/" . $document_name; @@ -717,7 +882,7 @@ public function exportToCcl($output_folder, $selectors_description, $extractors_ $types[$type] = 1; } } - echo "\n"; + $this->writeConsoleMessage("\n"); $stats_str = str_repeat(" ", $max_len_name); foreach ( array_keys($types) as $type ){ diff --git a/engine/include/export/ExportManager.php b/engine/include/export/ExportManager.php deleted file mode 100644 index 8960f190..00000000 --- a/engine/include/export/ExportManager.php +++ /dev/null @@ -1,644 +0,0 @@ -7, - "software_nam"=>7, - "event_nam"=>6, - "road_nam"=>5, - "facility_nam"=>4, - "company_nam"=>3, - "astronomical_nam"=>3, - "person_nam"=>2, - "city_nam"=>1); - var $cclDocuments = array(); - //input parameters - var $db = null; //instance of Database - var $corpus_ids = null; //array, value: id - var $subcorpus_ids = null; //array, value: id - var $document_ids = null; //array, value: id - var $flags = null; //array, key: flag name; value: array of flag values - var $annotation_layers = null; //array, value: id - var $annotation_names = null; //array, value: type name - var $folder = null; //string - var $relation_set_ids = null; - var $relation_type_ids = null; - var $index_flags = null; //array, value: corpora_flags.corpora_flag_id or corpora_flags.short - var $index_flag_ids = array(); //array, value: corpora_flags.corpora_flag_id - var $index_flag_paths = array(); //array, key: corpora_flags.short(lowercase, "_" instead of " "), value: array of strings (paths) - var $report_flag_ids = array(); //array, key: report_id; value: array (value: corpora_flags.short) - - var $split_documents = false; - var $separate_relations = false; - - var $iob_file_name = false; - - var $report_ids = array(); //array, value: id - var $reports = array(); //array, key: report id; value: report - var $metadata = array(); - var $tokens = array(); //array, key: report id; value: token - var $tags = array(); //array, key: report id; value: array (key: token_id, value: tag) - var $annotations = array(); //array, key: report id; value: annotation - var $relations = array(); - var $annotation_lemmas = array(); - var $annotation_properties = array(); - - var $verbose = false; - var $no_disamb = false; - - function setCorpusIds($corpus_ids){ - $this->corpus_ids = $corpus_ids; - } - - function setSubcorpusIds($subcorpus_ids){ - $this->subcorpus_ids = $subcorpus_ids; - } - - function setDocumentIds($document_ids){ - $this->document_ids = $document_ids; - } - - function setFlags($flags){ - $this->flags = $flags; - } - - function setAnnotationLayers($annotation_layers){ - $this->annotation_layers = $annotation_layers; - } - - function setAnnotationNames($annotation_names){ - $this->annotation_names = $annotation_names; - } - - function setRelationSetIds($relation_set_ids){ - $this->relation_set_ids = $relation_set_ids; - } - - function setRelationTypeIds($relation_type_ids){ - $this->relation_type_ids = $relation_type_ids; - } - - function setIndexFlags($index_flags){ - if ($index_flags){ - $this->index_flags = array(); - foreach($index_flags as $item){ - $this->index_flags[] = mb_strtolower($item); - } - } - } - - function setDb($db){ - assert('$db instanceof Database'); - $this->db = $db; - } - - function setFolder($folder){ - $this->folder = $folder; - } - - function setSplit($split_documents){ - $this->split_documents = $split_documents; - } - - function setSeparateRelations($separate_relations){ - $this->separate_relations = $separate_relations; - } - - function setIob($iob_file_name){ - $this->iob_file_name = $iob_file_name; - } - - function log($text){ - if ( $this->verbose ) - echo date("\r[H:i:s]") . " $text\n"; - } - - function setVerbose($verbose){ - $this->verbose = $verbose; - } - - function setNoDisamb($no_disamb){ - $this->no_disamb = $no_disamb; - } - - /** - * Wczytuje dokumenty do eksportu na podstawie ustawionych filtrów. - */ - function readDocuments(){ - $reports = DbReport::getReports($this->corpus_ids, $this->subcorpus_ids, - $this->document_ids, $this->flags); - - foreach ($reports as &$r) - $this->reports[$r['id']] = &$r; - $this->report_ids = array_keys($this->reports); - $this->log(sprintf("Number of documents to export: %d", count($this->report_ids))); - if ($this->index_flags){ - $this->getIndexFlags(); - if ($this->no_content){ - $this->writeRawIndexes(); - } - } - } - - function getIndexFlags(){ - echo date("[H:i:s] ") . " - get index flags\n"; - $index_flags = DbCorporaFlag::getCorporaFlagIds($this->index_flags); - - //check if all given flags exist in database - $flag_errors = array(); - $flag_ids = array(); - $flag_shorts_orig = array(); - if (empty($index_flags)){ - $e = new CclError(); - $e->setClassName("CclSetFactory"); - $e->setFunctionName("acquireData"); - $e->addObject("message", "flag error"); - $e->addComment("015 no given flag was found"); - $flag_errors[] = $e; - } - else { - $flag_shorts = array(); - foreach ($index_flags as $item){ - $flag_ids[] = $item['corpora_flag_id']; - $flag_lower = mb_strtolower($item['short']);; - if (!in_array($flag_lower, $flag_shorts)){ - $flag_shorts[] = $flag_lower; - } - } - foreach ($this->index_flags as $item){ - if (! (in_array($item, $flag_ids) || in_array($item, $flag_shorts)) ){ - $e = new CclError(); - $e->setClassName("CclSetFactory"); - $e->setFunctionName("acquireData"); - $e->addObject("message", "flag error"); - $e->addComment("016 flag \"$item\" not found"); - $flag_errors[] = $e; - } - } - } - if ($flag_errors){ - foreach ($flag_errors as $flag_error){ - print (string)$flag_error . "\n"; - } - exit("EXIT: flag error\n"); - } - else { - $this->index_flag_ids = $flag_ids; - - $report_flag_ids = DBReportFlag::getReportFlagData($this->report_ids, $flag_ids); - foreach ($report_flag_ids as $item){ - $report_id = $item['report_id']; - $short = $item['short']; - if (empty($this->report_flag_ids[$report_id])) - $this->report_flag_ids[$report_id] = array(); - $this->report_flag_ids[$report_id][] = mb_strtolower(str_replace(" ","_",$short)); - } - } - } - - /** - * Przygotowuje indeksy do zapisu. - */ - function processIndexes(){ - foreach ($this->report_flag_ids as $report_id=>$flag_shorts){ - $path = ""; - if ($this->split_documents) - $relativePath = preg_replace("/[^\p{L}|\p{N}]+/u","_",$this->reports[$report_id]['name']) . "/"; - foreach ($flag_shorts as $short){ - $path = $relativePath . str_pad($report_id,8,'0',STR_PAD_LEFT) . ".xml"; - if (empty($this->index_flag_paths[$short])) - $this->index_flag_paths[$short] = array(); - $this->index_flag_paths[$short][] = $path; - } - } - } - - /** - * Zapisuje indeksy dla flag. - */ - function writeIndexes(){ - $subfolder = $this->folder . "/"; - foreach($this->index_flag_paths as $index_name=>$paths){ - $filename = "index_" . $index_name . ".txt"; - $handle = fopen($subfolder . $filename, "w"); - sort($paths); - foreach ($paths as $path) - fwrite($handle, $path . "\n"); - fclose($handle); - if ( $this->verbose ) - echo sprintf(" - index: %4d in %s\n", count($paths), $filename); - } - } - - /** - * Wczytuje dane o treści dokumentów, tokenizacji, anotacjach i relacjach - * z bazy danych. - */ - function readContent(){ - $this->log("Reading content ..."); - $this->log(" a) reading tokens ..."); - $tokens = DbToken::getTokensByReportIds($this->report_ids); - foreach ($tokens as &$token){ - $report_id = $token['report_id']; - if (!array_key_exists($report_id, $this->tokens)) - $this->tokens[$report_id] = array(); - $this->tokens[$report_id][] = &$token; - } - - $this->log(" b) reading tags ..."); - $tags = DbTag::getTagsByReportIds($this->report_ids); - - $this->log(" c) assigning tags to tokens ..."); - foreach ($tags as $tag){ - $report_id = $tag['report_id']; - $token_id = $tag['token_id']; - if ( !isset($this->tags[$report_id]) ) - $this->tags[$report_id] = array(); - if ( !isset($this->tags[$report_id][$token_id]) ) - $this->tags[$report_id][$token_id] = array(); - $this->tags[$report_id][$token_id][] = $tag; - } - - /** Reorganize tags */ - foreach ($this->tags as $report_id=>$tokens){ - foreach ($tokens as $token_id=>$tags){ - $ign = null; - $other = array(); - foreach ($tags as $i_tag=>$tag){ - if ($this->no_disamb) - $this->tags[$report_id][$token_id][$i_tag]['disamb'] = 0; - - if ($tag['ctag'] == "ign") - $ign = $tag; - else - $other[] = $tag; - } - /* Jeżeli jedną z interpretacji jest ign, to usuń pozostałe. */ - if ($this->no_disamb && $ign) - $this->tags[$report_id][$token_id] = array($ign); - elseif ($ign) - $this->tags[$report_id][$token_id] = array_merge(array($ign), $other); - } - } - - $this->log(" d) reading annotations ..."); - $annotations = DbAnnotation::getAnnotationsBySets($this->report_ids, - $this->annotation_layers, $this->annotation_names); - foreach ($annotations as &$annotation){ - $report_id = $annotation['report_id']; - if (!array_key_exists($report_id, $this->annotations)) - $this->annotations[$report_id] = array(); - $this->annotations[$report_id][] = &$annotation; - } - - $this->log(" e) reading relations ..."); - $relations = DbCorpusRelation::getRelationsBySets($this->report_ids, - $this->relation_set_ids, $this->relation_type_ids); - foreach ($relations as &$relation){ - $report_id = $relation['report_id']; - if (!array_key_exists($report_id, $this->relations)){ - $this->relations[$report_id] = array(); - } - $this->relations[$report_id][] = &$relation; - } - - $this->log(" f) reading annotation lemmas ..."); - //$this->annotation_lemmas = DbReportAnnotationLemma::getLemmasByReportsIds($this->report_ids); - $this->annotation_lemmas = DbReportAnnotationLemma::getLemmasBySets2($this->report_ids, $this->annotation_layers, $this->annotation_names); - - $this->log(" f) reading annotation attributes ..."); - $this->annotation_properties = DbReportAnnotationLemma::getPropertiesBySets2($this->report_ids, $this->annotation_layers, $this->annotation_names); - - - $this->log("Reading content is done."); - } - - /** - * Read documents metadata from the database. - */ - function readMetadata(){ - $corpora = array(); - $cnt=0; - foreach ($this->report_ids as $report_id){ - $cnt ++; - $report = $this->reports[$report_id]; - $corpora[$report['corpora']][] = $report['id']; - } - foreach ($corpora as $corpus_id => $report_ids){ - $corpus = DbCorpus::getCorpusById($corpus_id); - $ext = $corpus['ext']; - if ($ext){ - $exts = DbReport::getReportExtByIds($report_ids, $ext); - foreach ($exts as $ext){ - $this->metadata[$ext['id']] = $ext; - } - } - } - } - - /** - * Read documents segmentation, annotation and relations from databse. - */ - function processContent(){ - //$this->log("Processing content ..."); - $allReports = count($this->report_ids); - $cnt = 0; - foreach ($this->report_ids as $report_id){ - $cnt ++; - $report = $this->reports[$report_id]; - - $tokens = array(); - $tags = array(); - $annotations = array(); - $relations = array(); - $annotation_lemmas = array(); - $annotation_properties = array(); - - if (array_key_exists($report_id, $this->tokens)) - $tokens = &$this->tokens[$report_id]; - - if (array_key_exists($report_id, $this->tags)) - $tags = &$this->tags[$report_id]; - - if (array_key_exists($report_id, $this->annotations)) - $annotations = &$this->annotations[$report_id]; - - if (array_key_exists($report_id, $this->relations)) - $relations = &$this->relations[$report_id]; - - if (array_key_exists($report_id, $this->annotation_lemmas)) - $annotation_lemmas = $this->annotation_lemmas[$report_id]; - if (array_key_exists($report_id, $this->annotation_properties)) - $annotation_properties = $this->annotation_properties[$report_id]; - - try{ - $ccl = CclFactory::createFromReportAndTokens($report, $tokens, $tags); - - if (count($tokens)==0){ - $e = new CclError(); - $e->setClassName("CclSetFactory"); - $e->setFunctionName("create"); - $e->addObject("report", $report); - $e->addComment("010 no tokenization in report"); - $ccl->addError($e); - } - else { - $flags = DbReportFlag::getReportFlags($report_id); - $annotations = $this->filterAnnotationsByFlags($report_id, $flags, $annotations); - $relations = $this->filterRelationsByFlags($report_id, $flags, $relations); - CclFactory::setAnnotationsAndRelations($ccl, $annotations, $relations); - CclFactory::setAnnotationLemmas($ccl, $annotation_lemmas); - CclFactory::setAnnotationProperties($ccl, $annotation_properties); - } - - if (count($tags)==0){ - $e = new CclError(); - $e->setClassName("CclSetFactory"); - $e->setFunctionName("create"); - $e->addObject("report", $report); - $e->addComment("011 no tags in report"); - $ccl->addError($e); - } - - $this->cclDocuments[$report_id] = $ccl; - } - catch(Exception $ex){ - print "!!!!! FIX ME report_id = $report_id\n"; - } - } - //$this->log("Processing content ... done"); - } - - /** - * Write documents tokens, annotations and relations to files. - */ - function writeContent(){ - //$this->log("Writing content ... "); - if ($this->iob_file_name) - $this->_writeIob(); - else - $this->_writeCcl(); - //$this->log("Writing content ... done"); - } - - /** - * - */ - function _writeCcl(){ - $subfolder = $this->folder . "/"; - $relativePath = ""; - $failed = array(); - if (!is_dir($subfolder)) mkdir($subfolder, 0777); - foreach ($this->cclDocuments as $cclDocument){ - if ($this->split_documents){ - $relativePath = $cclDocument->getSubcorpus() . "/"; - $subfolder = $this->folder . "/" . $relativePath; - if (!is_dir($subfolder)) mkdir($subfolder, 0777); - } - - if (!$cclDocument->hasErrors()){ - if ($this->separate_relations){ - CclWriter::write($cclDocument, $subfolder . $cclDocument->getFileName() . ".xml", CclWriter::$CCL); - CclWriter::write($cclDocument, $subfolder . $cclDocument->getFileName() . ".rel.xml", CclWriter::$REL); - } - else - CclWriter::write($cclDocument, $subfolder . $cclDocument->getFileName() . ".xml", CclWriter::$CCLREL); - if ($this->index_flags){ - $report = $cclDocument->getReport(); - $report_id = $report['id']; - if (!empty($this->report_flag_ids[$report_id])){ - foreach ($this->report_flag_ids[$report_id] as $short){ - if (empty($this->index_flag_paths[$short])) - $this->index_flag_paths[$short] = array(); - $this->index_flag_paths[$short][] = $relativePath . $cclDocument->getFileName() . ".xml"; - } - } - } - } - else { - echo "ERROR in " . $cclDocument->getFileName() . " \n"; - $failed[] = $cclDocument->getFileName(); - $errors = $cclDocument->getErrors(); - foreach ($errors as $error){ - print (string)$error . "\n"; - } - } - } - - if ( count($failed) ){ - $this->log("[ERROR] Following documents were not saved because of errors:"); - foreach ($failed as $f) - $this->log(" - $f"); - } - } - - /** - * Write tokens and annotations to a single IOB file. - */ - function _writeIob(){ - $subfolder = $this->folder . "/"; - if (!is_dir($subfolder)) mkdir($subfolder, 0777); - $filename = $subfolder . $this->iob_file_name; - $writer = new IobWriter($filename, $this->channelPriority); - $writer->writeAll($this->cclDocuments); - $writer->close(); - $writer->printStats(); - } - - /** - * Save documents metadata to files. - */ - function writeMetadata(){ - $this->log("Writing medatada ..."); - $subfolder = $this->folder . "/"; - foreach ($this->reports as $r){ - $basic = array("id", "date", "title", "source", "author", "tokenization", "name:subcorpus"); - $lines = array(); - $lines[] = "[document]"; - - foreach ($basic as $b=>$br){ - $parts = split(":", $br); - $name = $parts[0]; - $name_target = $parts[1] ? $parts[1] : $name; - $lines[] = sprintf("%s = %s", $name_target, $r[$name]); - } - - if (isset($this->metadata[$r['id']])){ - $lines[] = ""; - $lines[] = "[metadata]"; - foreach ($this->metadata[$r['id']] as $key=>$val) - if ($key != "id"){ - $key = preg_replace("/[^\p{L}|\p{N}]+/u", "_", $key); - $lines[] = sprintf("%s = %s", $key, $val); - } - } - - if ($this->split_documents){ - $subfolder = $this->folder . "/" . - preg_replace("/[^\p{L}|\p{N}]+/u", "_", $r['name']) . "/"; - } - - $filename = $subfolder . str_pad($r['id'], 8, "0", STR_PAD_LEFT) . ".ini"; - $f = fopen($filename, "w"); - fwrite($f, implode("\n", $lines)); - fclose($f); - } - } - - /** - * Removes annotations according to flags. If there is a flag - * for fiven layer of annotations, the flag for document must be set to 3 or 4. - * In other case the annotation is discarded. - * - * @param $flags --- array of document flags and values. - * @param $annotations --- array of annotations. - */ - function filterAnnotationsByFlags($report_id, $flags, $annotations){ - $annotatons_filtered = array(); - $skipped = array(); - foreach ($annotations as $an){ - $group_id = intval($an['group_id']); - $keep = false; - - switch ( $group_id ) { - case 1: - $keep = isset($flags[FLAG_NAMES]) - && $this->flagReady($flags[FLAG_NAMES]); - break; - - case 2: - $keep = isset($flags[FLAG_WSD]) - && $this->flagReady($flags[FLAG_WSD]); - break; - - case 7: - $keep = isset($flags[FLAG_CHUNKS]) - && $this->flagReady($flags[FLAG_CHUNKS]); - break; - - default: - $keep = true; - break; - } - - if ($keep){ - $annotatons_filtered[] = $an; - } - else{ - $skipped[$an['name']] = 1; - } - } - - if (count($skipped) && $this->verbose){ - echo sprintf(">> [id=%d] Skipped annotations: %s\n", - $report_id, implode(", ", array_keys($skipped))); - } - - return $annotatons_filtered; - } - - /** - * - */ - function filterRelationsByFlags($report_id, $flags, $relations){ - $relations_filtered = array(); - $skipped = array(); - foreach ($relations as $rel){ - $group_id = intval($rel['relation_set_id']); - $keep = false; - - switch ( $group_id ) { - case 1: /* Chunks relations */ - $keep = isset($flags[FLAG_CHUNKS_REL]) - && $this->flagReady($flags[FLAG_CHUNKS_REL]); - break; - - case 2: /* Names relations */ - $keep = isset($flags[FLAG_NAMES_REL]) - && $this->flagReady($flags[FLAG_NAMES_REL]); - break; - - case 3: /* Coreference */ - $keep = isset($flags[FLAG_COREF]) - && $this->flagReady($flags[FLAG_COREF]); - break; - - default: - $keep = true; - break; - } - - if ($keep){ - $relations_filtered[] = $rel; - } - else{ - $skipped[$rel['name']] = 1; - } - } - - if (count($skipped) && $this->verbose){ - echo sprintf(">> [id=%d] Skipped relations: %s\n", - $report_id, implode(", ", array_keys($skipped))); - } - - return $relations_filtered; - } - - /** - * - */ - function flagReady($value){ - return in_array(intval($value), array(3,4)); - } -} - - - - -?> diff --git a/engine/include/export/FileWriter.php b/engine/include/export/FileWriter.php new file mode 100644 index 00000000..44c6cda0 --- /dev/null +++ b/engine/include/export/FileWriter.php @@ -0,0 +1,27 @@ +writeTextToFile($fileName,$textContent); + + } // writeJSONToFile() + +} // FileWriter class diff --git a/engine/include/export/XmlFactory.php b/engine/include/export/XmlFactory.php new file mode 100644 index 00000000..9d08818e --- /dev/null +++ b/engine/include/export/XmlFactory.php @@ -0,0 +1,16 @@ +setCclProperties($annotations,$relations,$lemmas,$attributes); + // export from $ccl to files + $writer = new CclWriter(); + $writer->write($ccl, $filePathWithoutExt.".xml", CclWriter::$CCL); + $writer->write($ccl, $filePathWithoutExt.".rel.xml", CclWriter::$REL); + + } // exportToXmlAndRelxml() + +} // XmlFactory class diff --git a/engine/include/functions/func_roles.php b/engine/include/functions/func_roles.php index e30369ba..e02426a3 100644 --- a/engine/include/functions/func_roles.php +++ b/engine/include/functions/func_roles.php @@ -11,7 +11,11 @@ function hasUserSystemRole($user, $anyRole){ if (in_array(ROLE_SYSTEM_USER_PUBLIC, $anyRole)){ return true; } else { - $userRoles = array_keys(is_array($user['role']) ? $user['role'] : array(ROLE_SYSTEM_USER_PUBLIC=>"")); + if(isset($user['role'])) { + $userRoles = array_keys(is_array($user['role']) ? $user['role'] : array(ROLE_SYSTEM_USER_PUBLIC=>"")); + } else { + $userRoles = array(ROLE_SYSTEM_USER_PUBLIC=>""); + } return count(array_intersect($userRoles, $anyRole)) > 0; } } @@ -47,7 +51,11 @@ function hasRole($role){ */ function hasCorpusRole($role){ global $corpus, $user; - return isset($corpus['role'][$user['user_id']][$role]) || isCorpusOwner(); + $defined = isset($user['user_id']) + && isset($corpus['role']) + && isset($corpus['role'][$user['user_id']]) + && isset($corpus['role'][$user['user_id']][$role]); + return $defined || isCorpusOwner(); } /** @@ -56,6 +64,12 @@ function hasCorpusRole($role){ */ function isCorpusOwner(){ global $corpus, $user; + if( !isset($user['user_id']) ) { + return False; + } + if( !isset($corpus['user_id']) ) { + return False; // maybe True ? + } return $user['user_id'] == $corpus['user_id']; } diff --git a/engine/include/integrity/CCclIntegrity.php b/engine/include/integrity/CCclIntegrity.php index 24eca50d..5fcc4857 100644 --- a/engine/include/integrity/CCclIntegrity.php +++ b/engine/include/integrity/CCclIntegrity.php @@ -50,7 +50,7 @@ static function checkXSDContent($content){ $content = preg_replace('/xlink:href="[^"]*"/', "", $content); $c = new MyDOMDocument(); $c->loadXML($content); - $c->schemaValidate(Config::Config()->get_path_engine()."/resources/synat/premorph.xsd"); + $c->schemaValidate(Config::Cfg()->get_path_engine()."/resources/synat/premorph.xsd"); return array("count"=> count($c->errors),"data"=>$c->errors); } diff --git a/engine/include/structs/CclChunk.php b/engine/include/structs/CclChunk.php new file mode 100644 index 00000000..6b83ddfa --- /dev/null +++ b/engine/include/structs/CclChunk.php @@ -0,0 +1,63 @@ +setSentenceIndexInTokens(count($this->sentences)); + $this->sentences[] = $sentence; + } + + function setType($type){ + $this->type = $type; + } + + function setId($id){ + $this->id = $id; + } + + function getSentences(){ + return $this->sentences; + } + + function getId(){ + return $this->id; + } + + function getType(){ + return $this->type; + } + + public function setChunkIndexInTokens($chunkIndex) { + foreach($this->sentences as $sentence) { + $sentence->setChunkIndexInTokens($chunkIndex); + } + } // setParentIndexesInTokens + + public function getSentenceByIndex($sentenceIndex){ + // sentenceIndex may be digit 0 + if( is_numeric($sentenceIndex) and ($sentenceIndex < count($this->sentences)) ) { + return $this->sentences[$sentenceIndex]; + } else { + return null; + } + } // getSentenceByIndex + +} // CclChunk class + +?> diff --git a/engine/include/structs/CclStruct.php b/engine/include/structs/CclDocument.php similarity index 54% rename from engine/include/structs/CclStruct.php rename to engine/include/structs/CclDocument.php index 11d95472..a53b9500 100644 --- a/engine/include/structs/CclStruct.php +++ b/engine/include/structs/CclDocument.php @@ -25,7 +25,7 @@ class CclDocument{ var $char2token = array(); function addError($error){ - assert('$error instanceof CclError'); + assert($error instanceof CclError); $this->errors[] = $error; } @@ -59,13 +59,13 @@ function setSubcorpus($subcorpus){ } function addChunk($chunk){ - assert('$chunk instanceof CclChunk'); + assert($chunk instanceof CclChunk); $chunk->setChunkIndexInTokens(count($this->chunks)); $this->chunks[] = $chunk; } function addToken($token){ - assert('$token instanceof CclToken'); + assert($token instanceof CclToken); $index = count($this->tokens); $this->tokens[] = $token; for ( $i=$token->getFrom(); $i<=$token->getTo(); $i++) @@ -97,9 +97,10 @@ function getRelations(){ } function setAnnotationLemma($annotation_lemma){ - $type = $annotation_lemma['type']; - if ( !isset($this->char2token[$annotation_lemma['from']])){ + if ( !isset($annotation_lemma['from']) + || !isset($this->char2token[$annotation_lemma['from']]) + ){ $e = new CclError(); $e->setClassName("CclDocument"); $e->setFunctionName("setAnnotationLemma"); @@ -123,6 +124,8 @@ function setAnnotationLemma($annotation_lemma){ $token = & $this->tokens[$i]; if (! $token->setAnnotationLemma($annotation_lemma)){ + // 'dead code' - actually CclToken->setAnnotationLemma() + // returns always true. For invalid data too. $e = new CclError(); $e->setClassName("CclDocument"); $e->setFunctionName("setAnnotationLemma"); @@ -134,9 +137,10 @@ function setAnnotationLemma($annotation_lemma){ } function setAnnotationProperty($annotation_property){ - $type = $annotation_property['type']; - if ( !isset($this->char2token[$annotation_property['from']])){ + if ( !isset($annotation_property['from']) + || !isset($this->char2token[$annotation_property['from']]) + ){ $e = new CclError(); $e->setClassName("CclDocument"); $e->setFunctionName("setAnnotation"); @@ -146,7 +150,9 @@ function setAnnotationProperty($annotation_property){ return; } - if ( !isset($this->char2token[$annotation_property['to']])){ + if ( !isset($annotation_property['to']) + || !isset($this->char2token[$annotation_property['to']]) + ){ $e = new CclError(); $e->setClassName("CclDocument"); $e->setFunctionName("setAnnotation"); @@ -174,9 +180,11 @@ function setAnnotationProperty($annotation_property){ function setAnnotation($annotation){ $found = false; $sentence = null; //parent sentence - $type = $annotation['type']; + $type = isset($annotation['type']) ? $annotation['type'] :''; - if ( !isset($this->char2token[$annotation['from']]) ){ + if ( !isset($annotation['from']) + || !isset($this->char2token[$annotation['from']]) + ){ $e = new CclError(); $e->setClassName("CclDocument"); $e->setFunctionName("setAnnotation"); @@ -205,8 +213,8 @@ function setAnnotation($annotation){ } $found = true; } - if ( $annotation['value'] ){ - $prop_name = sprintf("sense:%s", $annotation['name']); + if ( isset($annotation['value']) && $annotation['value'] ){ + $prop_name = sprintf("sense:%s", $annotation['type']); $token->prop[$prop_name] = $annotation['value']; } if (! $token->setAnnotation($annotation,$this->getSentenceByToken($token)->channels)){ @@ -410,483 +418,7 @@ protected function getSentenceByToken($token){ return null; } // getSentenceByToken -} -class CclChunk{ - var $id; // optional - var $type; //required - var $sentences = array(); - - function addSentence($sentence){ - assert('$sentence instanceof CclSentence'); - $sentence->setSentenceIndexInTokens(count($this->sentences)); - $this->sentences[] = $sentence; - } - - function setType($type){ - $this->type = $type; - } - - function setId($id){ - $this->id = $id; - } - - function getSentences(){ - return $this->sentences; - } - - function getId(){ - return $this->id; - } - - function getType(){ - return $this->type; - } - - public function setChunkIndexInTokens($chunkIndex) { - foreach($this->sentences as $sentence) { - $sentence->setChunkIndexInTokens($chunkIndex); - } - } // setParentIndexesInTokens - - public function getSentenceByIndex($sentenceIndex){ - // sentenceIndex may be digit 0 - if( is_numeric($sentenceIndex) and ($sentenceIndex < count($this->sentences)) ) { - return $this->sentences[$sentenceIndex]; - } else { - return null; - } - } // getSentenceByIndex - -} - -class CclSentence{ - var $id; // optional - var $tokens = array(); - var $channels = array(); //key: annotation_type, value: last channel number - - - function setId($id){ - $this->id = $id; - } - - function addToken($token){ - assert('$token instanceof CclToken'); - $this->tokens[] = $token; - } - - function getTokens(){ - return $this->tokens; - } - - function getId(){ - return $this->id; - } - - function setChannel($type, $value){ - $this->channels[$type] = $value; - } - - function incChannel($type){ - if (!array_key_exists($type, $this->channels)) - $this->channels[$type]=1; - else $this->channels[$type]++; - } - - function fillChannel($type){ - foreach ($this->tokens as $token){ - $token->fillChannel($type); - } - } - - function getChannel($type){ - if ($type == null) return 0; - if (!array_key_exists($type, $this->channels)) - return 0; - else return $this->channels[$type]; - } - - public function setSentenceIndexInTokens($sentenceIndex) { - foreach($this->tokens as $token) { - $token->setParentSentenceIndex($sentenceIndex); - } - } // setSentenceIndexInTokens - - public function setChunkIndexInTokens($chunkIndex) { - foreach($this->tokens as $token) { - $token->setParentChunkIndex($chunkIndex); - } - } // setChunkIndexInTokens - -} - -class CclToken{ - var $id = null; - var $orth = null; - // If token is preceded by a white space - var $ns = false; - var $lexemes = array(); - var $from = null; - var $to = null; - private $parentSentenceIndex = null; - // parent sentence index in chunk sentences[] array - private $parentChunkIndex = null; - // parent chunk index in document chunks[] array - var $channels = array(); //same as in sentence, but with unique according number - var $prop = null; - - function setOrth($orth){ - $this->orth = $orth; - } - - function setNs($ns){ - $this->ns = $ns; - } - - function setId($id){ - $this->id = $id; - } - - function setFrom($from){ - $this->from = $from; - } - - function setTo($to){ - $this->to = $to; - } - - function setAnnotationLemma($annotation_lemma){ - $this->prop[$annotation_lemma["type"].":lemma"] = $annotation_lemma["lemma"]; - return true; - } - - function setAnnotationProperty($annotation_property){ - $this->prop[$annotation_property["type"].":".$annotation_property["name"]] = $annotation_property["value"]; - return true; - } - - function setAnnotation($annotation,$parentChannels = null){ - - $type = $annotation['type']; - if ($type=="sense"){ - /* - * Caution! Now WSD annotations are not part of any relations - * and all instances (even having more than 1 name in db) can - * be renumbered in 'sense' channel, e.g. - * [metrów] as wsd_m got number 6, but in db this instance - * was described also as wsd_metr (#3767), so there will be next - * assignment of channel number from parent sentence, which will be 7. - */ - - //if more than 1 annotation with the same name length covers one token (#3767): - if ($this->prop && (count($this->prop) == count($annotation['value'])) ){ - return false; - } - - else if (!$this->prop || (count($this->prop) < count($annotation['value'])) ){ - $this->prop = $annotation['value']; - } - - $this->channels[$type] = $annotation['id']; - } - else { - if (array_key_exists($type, $this->channels) && $this->channels[$type]!=0 ){ - return false; - } - - if (is_array($parentChannels) && !array_key_exists($type, $parentChannels) ){ - return false; - } - - $this->channels[$type] = $annotation['id']; - } - - return true; - } - - function setContinuousAnnotation2($type,$parentChannels = null){ - - // $parentChannels may be null or sth - if(!is_array($parentChannels)) - return false; - //annotation might exist in more than one sentence - if (!array_key_exists($type, $parentChannels) ) - return false; - $this->channels[$type] = $parentChannels[$type]; - return true; - } - - function fillChannel($type){ - if (!array_key_exists($type, $this->channels)) - $this->channels[$type]=0; - } - - function addLexeme($lexeme){ - $this->lexemes[] = $lexeme; - } - - function getOrth(){ - return $this->orth; - } - - function getNs(){ - return $this->ns; - } - - function getLexemes(){ - return $this->lexemes; - } - - function getChannels(){ - return $this->channels; - } - - function getChannel($type){ - if (!array_key_exists($type, $this->channels)) - return 0; - return $this->channels[$type]; - } - - function getId(){ - return $this->id; - } - - function getFrom(){ - return $this->from; - } - - function getTo(){ - return $this->to; - } - - function isIn($annotation){ - return ($this->from >= $annotation['from'] && $this->to <= $annotation['to']); - } - - /** - * Return base for first disamb lexem. - * If no dismb lexems is found then the base of a first lexem is returned. - */ - function getBase(){ - foreach ($this->lexemes as $lexem){ - if ($lexem->getDisamb()){ - return $lexem->getBase(); - } - } - if ( count($this->lexemes) > 0){ - return $this->lexemes[0]->getBase(); - } - return null; - } - - public function setParentSentenceIndex($parentSentenceIndex) { - $this->parentSentenceIndex = $parentSentenceIndex; - } // setParentSentenceIndex - - public function getParentSentenceIndex() { - return $this->parentSentenceIndex; - } // getParentSentenceIndex - - public function setParentChunkIndex($parentChunkIndex) { - $this->parentChunkIndex = $parentChunkIndex; - } // setParentChunkIndex - - public function getParentChunkIndex() { - return $this->parentChunkIndex; - } // getParentChunkIndex - -} - -class CclLexeme{ - var $disamb = null; - var $base = null; - var $ctag = null; - - function setDisamb($disamb){ - $this->disamb = $disamb; - } - - function setBase($base){ - $this->base = $base; - } - - function setCtag($ctag){ - $this->ctag = $ctag; - } - - function getDisamb(){ - return $this->disamb; - } - - function getBase(){ - return $this->base; - } - - function getCtag(){ - return $this->ctag; - } - -} - -class CclRelation{ - var $name = null; - var $set = null; - var $fromSentence = null; - var $fromChannel = null; - var $toSentence = null; - var $toChannel = null; - var $fromType = null; - var $toType = null; - - function getName(){ - return $this->name; - } - - function getSet(){ - return $this->set; - } - - function getFromSentence(){ - return $this->fromSentence; - } - - function getToSentence(){ - return $this->toSentence; - } - - function getFromChannel(){ - return $this->fromChannel; - } - - function getToChannel(){ - return $this->toChannel; - } - - function getFromType(){ - return $this->fromType; - } - - function getToType(){ - return $this->toType; - } - - function setName($name){ - $this->name = $name; - } - - function setSet($set){ - $this->set = $set; - } - - function setFromSentence($fromSentence){ - $this->fromSentence = $fromSentence; - } - - function setToSentence($toSentence){ - $this->toSentence = $toSentence; - } - - function setFromChannel($fromChannel){ - $this->fromChannel = $fromChannel; - } - - function setToChannel($toChannel){ - $this->toChannel = $toChannel; - } - - function setFromType($fromType){ - $this->fromType = $fromType; - } - - function setToType($toType){ - $this->toType = $toType; - } - -} - -class CclError{ - var $className = null; - var $functionName = null; - var $objects = array(); - var $comments = array(); - - - function setClassName($className){ - $this->className = $className; - } - - function setFunctionName($functionName){ - $this->functionName = $functionName; - } - - function addObject($key, $value){ - $this->objects[$key] = $value; - } - - function addComment($value){ - $this->comments[] = $value; - } - - - function getClassName(){ - return $this->className; - } - - function getFunctionName(){ - return $this->functionName; - } - - function getObjects(){ - return $this->objects; - } - - function getComments(){ - return $this->comments; - } - - - function __toString(){ - $str = "---------------------ERROR-------------------------\n"; - $str .= "class: {$this->className}\n"; - $str .= "function: {$this->functionName}\n"; - $str .= "comments: \n"; - foreach ($this->comments as $comment) - $str .= " $comment\n"; - $str .= "objects: \n"; - - foreach ($this->objects as $key=>$obj){ - if ($key=="token"){ - $str .= " Token:\n"; - $str .= " Orth: {$obj->getOrth()}\n"; - $str .= " From: {$obj->getFrom()}\n"; - $str .= " To : {$obj->getTo()}\n"; - } - elseif (strpos($key, "annotation") === 0){ - $str .= " Annotation:\n"; - $str .= " Key : $key \n"; - $str .= " Type: {$obj['type']}\n"; - $str .= " From: {$obj['from']}\n"; - $str .= " To : {$obj['to']}\n"; - $str .= " Text: {$obj['text']}\n"; - } - elseif ($key=="relation"){ - $str .= " Relation:\n"; - $str .= " Source id: {$obj['source_id']}\n"; - $str .= " Target id: {$obj['target_id']}\n"; - } - elseif ($key=="message"){ - $str .= "message: $obj"; - } - else { - $str .= " $key\n"; - $str .= " build your own user-friendly dump\n"; - } - } - return $str; - } - - - -} +} // CclDocument ?> diff --git a/engine/include/structs/CclError.php b/engine/include/structs/CclError.php new file mode 100644 index 00000000..fac4713b --- /dev/null +++ b/engine/include/structs/CclError.php @@ -0,0 +1,92 @@ +className = $className; + } + + function setFunctionName($functionName){ + $this->functionName = $functionName; + } + + function addObject($key, $value){ + $this->objects[$key] = $value; + } + + function addComment($value){ + $this->comments[] = $value; + } + + + function getClassName(){ + return $this->className; + } + + function getFunctionName(){ + return $this->functionName; + } + + function getObjects(){ + return $this->objects; + } + + function getComments(){ + return $this->comments; + } + + + function __toString(){ + $str = "---------------------ERROR-------------------------\n"; + $str .= "class: {$this->className}\n"; + $str .= "function: {$this->functionName}\n"; + $str .= "comments: \n"; + foreach ($this->comments as $comment) + $str .= " $comment\n"; + $str .= "objects: \n"; + + foreach ($this->objects as $key=>$obj){ + if ($key=="token"){ + $str .= " Token:\n"; + $str .= " Orth: {$obj->getOrth()}\n"; + $str .= " From: {$obj->getFrom()}\n"; + $str .= " To : {$obj->getTo()}\n"; + } + elseif (strpos($key, "annotation") === 0){ + $str .= " Annotation:\n"; + $str .= " Key : $key \n"; + $str .= " Type: {$obj['type']}\n"; + $str .= " From: {$obj['from']}\n"; + $str .= " To : {$obj['to']}\n"; + $str .= " Text: {$obj['text']}\n"; + } + elseif ($key=="relation"){ + $str .= " Relation:\n"; + $str .= " Source id: {$obj['source_id']}\n"; + $str .= " Target id: {$obj['target_id']}\n"; + } + elseif ($key=="message"){ + $str .= "message: $obj"; + } + else { + $str .= " $key\n"; + $str .= " build your own user-friendly dump\n"; + } + } + return $str; + } + +} // CclError class + +?> diff --git a/engine/include/structs/CclLexeme.php b/engine/include/structs/CclLexeme.php new file mode 100644 index 00000000..95c5f5b2 --- /dev/null +++ b/engine/include/structs/CclLexeme.php @@ -0,0 +1,40 @@ +disamb = $disamb; + } + + function setBase($base){ + $this->base = $base; + } + + function setCtag($ctag){ + $this->ctag = $ctag; + } + + function getDisamb(){ + return $this->disamb; + } + + function getBase(){ + return $this->base; + } + + function getCtag(){ + return $this->ctag; + } + +} // CclLexeme class + +?> diff --git a/engine/include/structs/CclRelation.php b/engine/include/structs/CclRelation.php new file mode 100644 index 00000000..e587c9b9 --- /dev/null +++ b/engine/include/structs/CclRelation.php @@ -0,0 +1,85 @@ +name; + } + + function getSet(){ + return $this->set; + } + + function getFromSentence(){ + return $this->fromSentence; + } + + function getToSentence(){ + return $this->toSentence; + } + + function getFromChannel(){ + return $this->fromChannel; + } + + function getToChannel(){ + return $this->toChannel; + } + + function getFromType(){ + return $this->fromType; + } + + function getToType(){ + return $this->toType; + } + + function setName($name){ + $this->name = $name; + } + + function setSet($set){ + $this->set = $set; + } + + function setFromSentence($fromSentence){ + $this->fromSentence = $fromSentence; + } + + function setToSentence($toSentence){ + $this->toSentence = $toSentence; + } + + function setFromChannel($fromChannel){ + $this->fromChannel = $fromChannel; + } + + function setToChannel($toChannel){ + $this->toChannel = $toChannel; + } + + function setFromType($fromType){ + $this->fromType = $fromType; + } + + function setToType($toType){ + $this->toType = $toType; + } + +} // CclRelation class + +?> diff --git a/engine/include/structs/CclSentence.php b/engine/include/structs/CclSentence.php new file mode 100644 index 00000000..e132527f --- /dev/null +++ b/engine/include/structs/CclSentence.php @@ -0,0 +1,75 @@ +id = $id; + } + + function addToken($token){ + assert($token instanceof CclToken); + $this->tokens[] = $token; + } + + function getTokens(){ + return $this->tokens; + } + + function getId(){ + return $this->id; + } + + function setChannel($type, $value){ + $this->channels[$type] = $value; + } + + function incChannel($type){ + if (!array_key_exists($type, $this->channels)) + $this->channels[$type]=1; + else $this->channels[$type]++; + } + + function fillChannel($type){ + foreach ($this->tokens as $token){ + $token->fillChannel($type); + } + } + + function getChannel($type){ + if ($type == null) return 0; + if (!array_key_exists($type, $this->channels)) + return 0; + else return $this->channels[$type]; + } + + public function setSentenceIndexInTokens($sentenceIndex) { + foreach($this->tokens as $token) { + $token->setParentSentenceIndex($sentenceIndex); + } + } // setSentenceIndexInTokens + + public function setChunkIndexInTokens($chunkIndex) { + foreach($this->tokens as $token) { + $token->setParentChunkIndex($chunkIndex); + } + } // setChunkIndexInTokens + +} // CclSentence class + +?> diff --git a/engine/include/structs/CclStruct2.php b/engine/include/structs/CclStruct2.php deleted file mode 100644 index ffe213d0..00000000 --- a/engine/include/structs/CclStruct2.php +++ /dev/null @@ -1,124 +0,0 @@ -name = $name; - $this->value = $value; - } - - function getXml(){ - return " name}\">{$this->value}\n"; - } -} - -class CclLexem { - public $disamb = null; - public $base = null; - public $ctag = null; - function __construct($disamb, $base, $ctag){ - $this->disamb = $disamb; - $this->base = htmlspecialchars($base); - $this->ctag = $ctag; - } - - function getXml(){ - //return ""; - $xml = $this->disamb ? " \n" : " \n"; - $xml .= " {$this->base}\n"; - $xml .= " {$this->ctag}\n"; - return $xml . " \n"; - } -} - -class CclToken { - public $orth = null; - public $lexemes = null; - public $channels = null; - public $ns = null; - - function __construct($orth){ - $this->orth = htmlspecialchars($orth); - $this->lexemes = array(); - $this->channels = array(); - $this->ns = false; - } - - function getXml($channelTypes){ - $xml = " \n"; - $xml .= " {$this->orth}\n"; - foreach ($this->lexemes as $lexeme) - $xml .= $lexeme->getXml(); - - foreach ($channelTypes as $annType) - $xml .= $this->channels[$annType]->getXml(); - if ($this->ns) return $xml . " \n \n"; - return $xml . " \n"; - - } -} - -class CclSentence { - public $tokens = null; - public $channelTypes = null; - public $id = null; - - function __construct($id){ - $this->tokens = array(); - $this->channelTypes = array(); - $this->id = $id; - } - - function getXml(){ - $usedTypes = array_keys($this->channelTypes); - $xml = " id}\">\n"; - foreach ($this->tokens as $token) - $xml .= $token->getXml($usedTypes); - return $xml . " \n"; - } -} - -class CclChunk { - public $id = null; - public $sentences = null; - function __construct($id){ - $this->id = $id; - $this->sentences = array(); - } - - function getXml(){ - $xml = " id}\">\n"; - foreach ($this->sentences as $sentence) - $xml .= $sentence->getXml(); - return $xml . " \n"; - } -} - -class CclDocument { - public $chunks = null; - - function __construct(){ - $this->chunks = array(); - } - - function getXml(){ - $xml = "\n"; - foreach ($this->chunks as $chunk) - $xml .= $chunk->getXml(); - return $xml . "\n"; - - } - -} - - - -?> diff --git a/engine/include/structs/CclToken.php b/engine/include/structs/CclToken.php new file mode 100644 index 00000000..54803dac --- /dev/null +++ b/engine/include/structs/CclToken.php @@ -0,0 +1,191 @@ +orth = $orth; + } + + function setNs($ns){ + $this->ns = $ns; + } + + function setId($id){ + $this->id = $id; + } + + function setFrom($from){ + $this->from = $from; + } + + function setTo($to){ + $this->to = $to; + } + + function setAnnotationLemma($annotation_lemma){ + $type = (isset($annotation_lemma["type"]) && ($annotation_lemma["type"])) ? $annotation_lemma["type"] : ''; + $lemma = (isset($annotation_lemma["lemma"]) && ($annotation_lemma["lemma"])) ? $annotation_lemma["lemma"] : null; + $this->prop[$type.":lemma"] = $lemma; + return true; + } + + function setAnnotationProperty($annotation_property){ + $this->prop[$annotation_property["type"].":".$annotation_property["name"]] = $annotation_property["value"]; + return true; + } + + public function setAnnotation($annotation,$parentChannels = null){ + + $type = $annotation['type']; + if ($type=="sense"){ + /* + * Caution! Now WSD annotations are not part of any relations + * and all instances (even having more than 1 name in db) can + * be renumbered in 'sense' channel, e.g. + * [metrów] as wsd_m got number 6, but in db this instance + * was described also as wsd_metr (#3767), so there will be next + * assignment of channel number from parent sentence, which will be 7. + */ + + //if more than 1 annotation with the same name length covers one token (#3767): + if ($this->prop && (count($this->prop) == count($annotation['value'])) ){ + return false; + } + + else if (!$this->prop || (count($this->prop) < count($annotation['value'])) ){ + $this->prop = $annotation['value']; + } + } + else { + if (array_key_exists($type, $this->channels) && $this->channels[$type]!=0 ){ + return false; + } + + if (is_array($parentChannels) && !array_key_exists($type, $parentChannels) ){ + return false; + } + } + // add to typed channel and return true if not exited earlier + $this->channels[$type] = $annotation['id']; + return true; + } // setAnnotation() + + function setContinuousAnnotation2($type,$parentChannels = null){ + + // $parentChannels may be null or sth + if(!is_array($parentChannels)) + return false; + //annotation might exist in more than one sentence + if (!array_key_exists($type, $parentChannels) ) + return false; + $this->channels[$type] = $parentChannels[$type]; + return true; + } + + function fillChannel($type){ + if (!array_key_exists($type, $this->channels)) + $this->channels[$type]=0; + } + + function addLexeme($lexeme){ + $this->lexemes[] = $lexeme; + } + + function getOrth(){ + return $this->orth; + } + + function getNs(){ + return $this->ns; + } + + function getLexemes(){ + return $this->lexemes; + } + + function getChannels(){ + return $this->channels; + } + + function getChannel($type){ + if (!array_key_exists($type, $this->channels)) + return 0; + return $this->channels[$type]; + } + + function getId(){ + return $this->id; + } + + function getFrom(){ + return $this->from; + } + + function getTo(){ + return $this->to; + } + + function isIn($annotation){ + return ($this->from >= $annotation['from'] && $this->to <= $annotation['to']); + } + + /** + * Return base for first disamb lexem. + * If no dismb lexems is found then the base of a first lexem is returned. + */ + function getBase(){ + foreach ($this->lexemes as $lexem){ + if ($lexem->getDisamb()){ + return $lexem->getBase(); + } + } + if ( count($this->lexemes) > 0){ + return $this->lexemes[0]->getBase(); + } + return null; + } + + public function setParentSentenceIndex($parentSentenceIndex) { + $this->parentSentenceIndex = $parentSentenceIndex; + } // setParentSentenceIndex + + public function getParentSentenceIndex() { + return $this->parentSentenceIndex; + } // getParentSentenceIndex + + public function setParentChunkIndex($parentChunkIndex) { + $this->parentChunkIndex = $parentChunkIndex; + } // setParentChunkIndex + + public function getParentChunkIndex() { + return $this->parentChunkIndex; + } // getParentChunkIndex + +} // CclToken class + +?> diff --git a/engine/include/utils/CCookieManager.php b/engine/include/utils/CCookieManager.php index 8e3b4482..078af7f3 100644 --- a/engine/include/utils/CCookieManager.php +++ b/engine/include/utils/CCookieManager.php @@ -32,7 +32,10 @@ static function getAnnotatorWSDAnnotationSet(){ * @return a list of annotation type identifiers */ static function getAnnotationTypeTreeAnnotationTypes($corpusId){ - $annotationTypesStr = trim(strval($_COOKIE[$corpusId . '_annotation_lemma_types'])); + $annotationTypesStr = + isset($_COOKIE[$corpusId . '_annotation_lemma_types']) + ? trim(strval($_COOKIE[$corpusId . '_annotation_lemma_types'])) + : ''; $annotationTypes = array(); foreach ( explode(",", $annotationTypesStr) as $id ){ $id = intval($id); @@ -80,7 +83,9 @@ static function getRelationAgreementRelationTypes($corpusId){ } static function getSelectedAnnotationTypeTreeAnnotationTypes($corpusId){ - $annotationTypesStr = trim(strval($_COOKIE[$corpusId . '_annotation_lemma_layers'])); + $annotationTypesStr = isset($_COOKIE[$corpusId . '_annotation_lemma_layers']) + ? trim(strval($_COOKIE[$corpusId . '_annotation_lemma_layers'])) + : '' ; $annotationTypes = array(); foreach ( explode(",", $annotationTypesStr) as $id ){ $id = intval($id); @@ -97,7 +102,8 @@ static function getSelectedAnnotationTypeTreeAnnotationTypes($corpusId){ * @return a list of relation set identifiers */ static function getRelationSets($corpusId){ - $relationSetsStr = trim(strval($_COOKIE[$corpusId . '_relation_sets'])); + $relationSetsStr = isset($_COOKIE[$corpusId . '_relation_sets']) + ? trim(strval($_COOKIE[$corpusId . '_relation_sets'])) :''; $relationSets = array(); foreach ( explode(",", $relationSetsStr) as $id ){ $id = intval($id); @@ -108,4 +114,4 @@ static function getRelationSets($corpusId){ return $relationSets; } -} \ No newline at end of file +} diff --git a/engine/include/utils/CDocumentConverter.php b/engine/include/utils/CDocumentConverter.php index 5c6608aa..74246f65 100644 --- a/engine/include/utils/CDocumentConverter.php +++ b/engine/include/utils/CDocumentConverter.php @@ -13,7 +13,7 @@ class DocumentConverter{ */ static function wcclDocument2AnnotatedDocument($wccl){ - $doc = &new AnnotatedDocument($wccl->name); + $doc = new AnnotatedDocument($wccl->name); $sentence_id = 1; $sentencecs = array(); @@ -22,19 +22,19 @@ static function wcclDocument2AnnotatedDocument($wccl){ foreach($wccl->chunks as $c){ - $chunk = &new AnnotatedDocumentChunk($c->id); + $chunk = new AnnotatedDocumentChunk($c->id); $doc->addChunk($chunk); foreach($c->sentences as $s){ - $sentene = &new AnnotatedDocumentSentence($s->id); + $sentene = new AnnotatedDocumentSentence($s->id); $chunk->addSentence($sentene); $token_id = 1; $annotation_id = 1; foreach($s->tokens as &$t){ - $token = &new AnnotatedDocumentToken($token_id++, $t->orth, $t->ns); + $token = new AnnotatedDocumentToken($token_id++, $t->orth, $t->ns); $sentene->addToken($token); if (!is_array($t->lexemes) ){ @@ -44,7 +44,7 @@ static function wcclDocument2AnnotatedDocument($wccl){ foreach ($t->lexemes as $l){ - $lexem = &new AnnotatedDocumentLexem($l->base, $l->ctag, $l->disamb); + $lexem = new AnnotatedDocumentLexem($l->base, $l->ctag, $l->disamb); $token->addLexem($lexem); } } @@ -58,7 +58,7 @@ static function wcclDocument2AnnotatedDocument($wccl){ $t = $s->tokens[$i]; if ($t->channels[$name] != $last_num && $first_index !== null){ // dodaj anotacje - $ad = &new AnnotatedDocumentAnnotation($annotation_id++, $sentene, $first_index, $i-1, $name, trim($text)); + $ad = new AnnotatedDocumentAnnotation($annotation_id++, $sentene, $first_index, $i-1, $name, trim($text)); $sentene->addAnnotation($ad); $hash = sprintf("%s_%s_%s", $s->id, $name, $last_num); @@ -80,7 +80,7 @@ static function wcclDocument2AnnotatedDocument($wccl){ } } if ($last_num != 0){ - $ad = &new AnnotatedDocumentAnnotation($annotation_id++, $sentene, $first_index, $i-1, $name, trim($text)); + $ad = new AnnotatedDocumentAnnotation($annotation_id++, $sentene, $first_index, $i-1, $name, trim($text)); $sentene->addAnnotation($ad); $hash = sprintf("%s_%s_%s", $s->id, $name, $last_num); @@ -116,4 +116,4 @@ static function wcclDocument2AnnotatedDocument($wccl){ } -?> \ No newline at end of file +?> diff --git a/engine/include/utils/CHelperBootstrap.php b/engine/include/utils/CHelperBootstrap.php index ceebb64c..813331c6 100644 --- a/engine/include/utils/CHelperBootstrap.php +++ b/engine/include/utils/CHelperBootstrap.php @@ -70,7 +70,7 @@ static function transformCclToAnnotations($ccl){ // TODO: to remove static function chunkWithLiner2($text, $model){ - $liner2 = Config::Config()->get_path_liner2()."/liner2.sh"; + $liner2 = Config::Cfg()->get_path_liner2()."/liner2.sh"; $liner2 = "liner2"; $tmp_in = "/tmp/inforex_liner2_input.txt"; diff --git a/engine/include/utils/CHelperTokenize.php b/engine/include/utils/CHelperTokenize.php index c54328dc..f5987791 100644 --- a/engine/include/utils/CHelperTokenize.php +++ b/engine/include/utils/CHelperTokenize.php @@ -26,7 +26,7 @@ static function xcesToCcl($text){ static function tagWithTakipiWs($text, $guesser){ $text = preg_replace("/]+>/", "", $text); - $tagger = new WSTagger(Config::Config()->get_takipi_wsdl()); + $tagger = new WSTagger(Config::Cfg()->get_takipi_wsdl()); $tagger->tag($text, $guesser); $text_tagged = "".$tagger->tagged.""; return $text_tagged; @@ -44,7 +44,7 @@ static function tagPremorphWithWcrft2($text, $sentences=false){ $tmp = ".inforex_tokenize.tmp"; file_put_contents($tmp, $text); $cmd_template = 'cat %s | maca-analyse -qs morfeusz-nkjp -i %s -o ccl | wcrft-app %s -i ccl -o ccl - 2>/dev/null'; - $cmd = sprintf($cmd_template, $tmp, $input, Config::Config()->get_wcrft2_config()); + $cmd = sprintf($cmd_template, $tmp, $input, Config::Cfg()->get_wcrft2_config()); echo $cmd; $text_tagged = shell_exec($cmd); if (file_exists($tmp)) unlink($tmp); @@ -56,7 +56,7 @@ static function tagPremorphWithWcrft2Working($text, $sentences=false){ $tmp = ".inforex_tokenize.tmp"; file_put_contents($tmp, $text); $cmd_template = 'cat %s | wcrft-app %s -i premorph -o ccl - 2>/dev/null'; - $cmd = sprintf($cmd_template, $tmp, Config::Config()->get_wcrft2_config()); + $cmd = sprintf($cmd_template, $tmp, Config::Cfg()->get_wcrft2_config()); echo $cmd; $text_tagged = shell_exec($cmd); if (file_exists($tmp)) unlink($tmp); @@ -68,7 +68,7 @@ static function tagPlainWithWcrft2($text){ $tmp = ".inforex_tokenize.tmp"; file_put_contents($tmp, $text); $cmd_template = 'cat %s | maca-analyse -qs morfeusz-nkjp-official -i %s -o ccl | wcrft-app %s -i ccl -o ccl -A - 2>/dev/null'; - $cmd = sprintf($cmd_template, $tmp, $input, Config::Config()->get_wcrft2_config()); + $cmd = sprintf($cmd_template, $tmp, $input, Config::Cfg()->get_wcrft2_config()); $text_tagged = shell_exec($cmd); if (file_exists($tmp)) unlink($tmp); return $text_tagged; @@ -88,7 +88,7 @@ static function tagWithMaca($text, $format="xces"){ static function tagPremorphWithMacaWcrft($text, $useSentencer=false){ $input = $useSentencer ? "premorph" : "premorph-stream-nosent"; - $wmbt = sprintf("wcrft %s -d %s -i ccl -A -o ccl -", Config::Config()->get_wcrft_config(),Config::Config()->get_path_wcrft_model()); + $wmbt = sprintf("wcrft %s -d %s -i ccl -A -o ccl -", Config::Cfg()->get_wcrft_config(),Config::Cfg()->get_path_wcrft_model()); $text = escapeshellarg($text); $cmd = sprintf('echo %s | maca-analyse -qs morfeusz-nkjp -i %s -o ccl 2>/dev/null | %s 2>/dev/null', $text, $input, $wmbt); ob_start(); @@ -98,7 +98,7 @@ static function tagPremorphWithMacaWcrft($text, $useSentencer=false){ } static function tagPlainWithWcrft($text){ - $wcrft = sprintf("wcrft %s -d %s -i ccl -o ccl -", Config::Config()->get_wcrft_config(), Config::Config()->get_path_wcrft_model()); + $wcrft = sprintf("wcrft %s -d %s -i ccl -o ccl -", Config::Cfg()->get_wcrft_config(), Config::Cfg()->get_path_wcrft_model()); $cmd = sprintf('echo %s | maca-analyse -qs morfeusz-nkjp -i plain -o ccl | %s', escapeshellarg($text), $wcrft); ob_start(); $text_tagged = shell_exec($cmd); diff --git a/engine/include/utils/CReportContent.php b/engine/include/utils/CReportContent.php index 88f19223..3f727ad7 100644 --- a/engine/include/utils/CReportContent.php +++ b/engine/include/utils/CReportContent.php @@ -114,8 +114,8 @@ static function insertAnnotationsWithRelations(HtmlStr2 $htmlStr, $annotations, foreach ($annotations as $an) { try { $after = ""; - if ( isset($annotationRelations[$an[id]]) ){ - $after = implode("", $annotationRelations[$an[id]]); + if ( isset($annotationRelations[$an['id']]) ){ + $after = implode("", $annotationRelations[$an['id']]); } $htmlStr->insertTag($an['from'], sprintf("", $an['id'], $an['type'], $an['group_id'], $an['annotation_subset_id'], $an['lemma']), $an['to'] + 1, "$after"); @@ -141,9 +141,10 @@ static function insertAnnotationsWithRelations(HtmlStr2 $htmlStr, $annotations, * @return HtmlStr2 */ static function getHtmlStr($report){ - $content = $report['content']; + $content = isset($report['content']) ? $report['content'] :''; + $format = isset($report['format']) ? $report['format'] :''; // Escape html special characters for plain format - if ( $report['format'] == 'plain'){ + if ( $format == 'plain'){ $content = htmlspecialchars($content); } return new HtmlStr2($content, true); @@ -157,4 +158,4 @@ static function getHtmlStrForReport($report){ } return new HtmlStr2($content, true); } -} \ No newline at end of file +} diff --git a/engine/include/utils/CWcclImport.php b/engine/include/utils/CWcclImport.php index a3d92371..cbd9e854 100644 --- a/engine/include/utils/CWcclImport.php +++ b/engine/include/utils/CWcclImport.php @@ -185,8 +185,8 @@ function tag_document($ccl, $r){ } /** Sentences */ - if( Config::Config()->get_insertSentenceTags() && $useSentencer ) - Premorph::set_sentence_tag($report_id,Config::Config()->get_user()); + if( Config::Cfg()->get_insertSentenceTags() && $useSentencer ) + Premorph::set_sentence_tag($report_id,Config::Cfg()->get_user()); $db->execute("COMMIT"); diff --git a/engine/include/utils/PHPUnitTools.php b/engine/include/utils/PHPUnitTools.php new file mode 100644 index 00000000..2ba5583c --- /dev/null +++ b/engine/include/utils/PHPUnitTools.php @@ -0,0 +1,27 @@ + diff --git a/engine/include/utils/reportlist/filters/ReportFilterEnumFlag.php b/engine/include/utils/reportlist/filters/ReportFilterEnumFlag.php index eae2f035..c0670d04 100644 --- a/engine/include/utils/reportlist/filters/ReportFilterEnumFlag.php +++ b/engine/include/utils/reportlist/filters/ReportFilterEnumFlag.php @@ -22,7 +22,7 @@ function __construct($flagId, $flagName){ $this->template = "report_filters/inc_filter_flag.tpl"; } - function applyTo(&$sqlBuilder){ + function applyTo($sqlBuilder){ $flagKey = "fl_" . $this->flagId; $sqlBuilder->addJoinTable(new SqlBuilderJoin("reports_flags", $flagKey, "r.id = $flagKey.report_id AND $flagKey.corpora_flag_id = ?", array($this->flagId))); diff --git a/engine/include/writers/CCclWriter.php b/engine/include/writers/CCclWriter.php index 42329bf5..7a8d8083 100644 --- a/engine/include/writers/CCclWriter.php +++ b/engine/include/writers/CCclWriter.php @@ -11,8 +11,26 @@ class CclWriter{ public static $CCL = 2; public static $REL = 3; + protected function formatPropToXML($propTable) { + + $xml = ""; // for no data + if (($propTable) && is_array($propTable)) { + foreach ($propTable as $key=>$val) { + if (strpos($val, ';;') !== FALSE){ + $values = explode(";;", $val); + $xml .= sprintf(" %s\n", htmlspecialchars(str_replace("lemma", "lval", $key)), htmlspecialchars($values[0])); + $xml .= sprintf(" %s\n", htmlspecialchars(str_replace("lemma", "val", $key)), htmlspecialchars($values[1])); + } else { + $xml .= sprintf(" %s\n", htmlspecialchars($key), htmlspecialchars($val)); + } + } // foreach + } // if is_array + return $xml; + + } // formatPropToXML() - static function write($ccl, $filename, $mode){ + private function makeXmlData($ccl,$mode) { + $xml = "\n"; $xml .= "\n"; @@ -38,17 +56,7 @@ static function write($ccl, $filename, $mode){ } foreach ($channels as $type=>$number) $xml .= " {$number}\n"; - if ($token->prop){ - foreach ($token->prop as $key=>$val){ - if (strpos($val, ';;') !== FALSE){ - $values = explode(";;", $val); - $xml .= sprintf(" %s\n", htmlspecialchars(str_replace("lemma", "lval", $key)), htmlspecialchars($values[0])); - $xml .= sprintf(" %s\n", htmlspecialchars(str_replace("lemma", "val", $key)), htmlspecialchars($values[1])); - } - else - $xml .= sprintf(" %s\n", htmlspecialchars($key), htmlspecialchars($val)); - } - } + $xml.= $this->formatPropToXML($token->prop); $xml .= $token->ns ? " \n \n" : " \n"; } $xml .= " \n"; @@ -73,13 +81,17 @@ static function write($ccl, $filename, $mode){ } if ($mode==self::$CCL || $mode==self::$CCLREL) $xml .= "\n"; - $handle = fopen($filename, "w"); - fwrite($handle, $xml); - fclose($handle); - } - - + + return $xml; + + } // makeXmlData() + + public function write($ccl, $filename, $mode){ + + (new FileWriter()) -> writeTextToFile($filename,$this->makeXmlData($ccl,$mode)); + + } // write() -} +} // CclWriter class ?> diff --git a/engine/page/corpus_perspectives/PerspectivePerspectives.php b/engine/page/corpus_perspectives/PerspectivePerspectives.php index bb52b812..6b159e99 100644 --- a/engine/page/corpus_perspectives/PerspectivePerspectives.php +++ b/engine/page/corpus_perspectives/PerspectivePerspectives.php @@ -12,7 +12,7 @@ function execute() { $this->set_corpus_perspectives(); $this->set_users_perspectives(); - PerspectiveUsers_roles::set_users_roles(); + $this->set_users_roles(); } function set_corpus_perspectives(){ diff --git a/engine/page/corpus_perspectives/PerspectiveUsers_roles.php b/engine/page/corpus_perspectives/PerspectiveUsers_roles.php index 8d37d2a2..38b35b10 100644 --- a/engine/page/corpus_perspectives/PerspectiveUsers_roles.php +++ b/engine/page/corpus_perspectives/PerspectiveUsers_roles.php @@ -34,7 +34,7 @@ function set_users_roles(){ } $this->page->set('users_roles', $users_roles); } - + function set_corpus_roles(){ global $db; $corpus_roles = $db->fetch_rows("SELECT * FROM corpus_roles WHERE role != 'read'"); diff --git a/engine/page/page_administration_annotation_shared_attributes.php b/engine/page/page_administration_annotation_shared_attributes.php index f4411788..8422a1dc 100644 --- a/engine/page/page_administration_annotation_shared_attributes.php +++ b/engine/page/page_administration_annotation_shared_attributes.php @@ -11,4 +11,4 @@ class Page_administration_annotation_shared_attributes extends CPageAdministrati function execute(){ $this->set("sharedAttributes", CDbAnnotationSharedAttribute::getAll()); } -} \ No newline at end of file +} diff --git a/engine/page/page_administration_diagnostic_access.php b/engine/page/page_administration_diagnostic_access.php index 864eedab..ffb1aee2 100755 --- a/engine/page/page_administration_diagnostic_access.php +++ b/engine/page/page_administration_diagnostic_access.php @@ -21,11 +21,11 @@ function execute(){ $items = array(); - $validatorAjax = new PageAccessValidator(Config::Config()->get_path_engine(), "ajax"); + $validatorAjax = new PageAccessValidator(Config::Cfg()->get_path_engine(), "ajax"); $validatorAjax->process(); $items = array_merge($items, $validatorAjax->items); - $validatorPage = new PageAccessValidator(Config::Config()->get_path_engine(), "page"); + $validatorPage = new PageAccessValidator(Config::Cfg()->get_path_engine(), "page"); $validatorPage->process(); $items = array_merge($items, $validatorPage->items); diff --git a/engine/page/page_ccl_viewer.php b/engine/page/page_ccl_viewer.php index 66bb2b04..b42abdb2 100644 --- a/engine/page/page_ccl_viewer.php +++ b/engine/page/page_ccl_viewer.php @@ -253,14 +253,14 @@ function set_navigation_elements($elements, $htmlStr, &$chunksToInset, &$show_re function set_panels(){ - $this->set('showRight', $_COOKIE['showRight']=="true"?true:false); + $this->set('showRight', array_key_exists('showRight',$_COOKIE) and ($_COOKIE['showRight']=="true")?true:false); } function set_relation_sets(){ $sql = "SELECT * FROM relation_sets "; $relation_sets = $this->getDb()->fetch_rows($sql); - $types = explode(",",preg_replace("/\:1|id|\{|\}|\"|\\\/","",$_COOKIE['active_annotation_types'])); + $types = explode(",",preg_replace("/\:1|id|\{|\}|\"|\\\/","",array_key_exists('active_annotation_types',$_COOKIE)?$_COOKIE['active_annotation_types']:"")); foreach($relation_sets as $key => $rel_set) $relation_sets[$key]['active'] = ($_COOKIE['active_annotation_types'] ? (in_array($rel_set['relation_set_id'],$types) ? 1 : 0) : 1 ); $this->set('relation_sets', $relation_sets); diff --git a/engine/page/page_corpus_export.php b/engine/page/page_corpus_export.php index 7dbe1bc3..e1c8b30e 100644 --- a/engine/page/page_corpus_export.php +++ b/engine/page/page_corpus_export.php @@ -88,7 +88,7 @@ function getExports($corpus_id){ } static function getExportFilePath($export_id){ - return Config::Config()->get_path_exports().DIRECTORY_SEPARATOR.sprintf("inforex_export_%d.7z", $export_id); + return Config::Cfg()->get_path_exports().DIRECTORY_SEPARATOR.sprintf("inforex_export_%d.7z", $export_id); } } ?> diff --git a/engine/page/page_corpus_settings.php b/engine/page/page_corpus_settings.php index 6e0abf58..9ebed989 100644 --- a/engine/page/page_corpus_settings.php +++ b/engine/page/page_corpus_settings.php @@ -32,13 +32,13 @@ function execute(){ * js/page_report_{$subpage}_resize.js — kod JS odpowiedzialny za automatyczne dopasowanie okna do strony. * css/page_report_{$subpage}.css — style CSS występujące tylko w danej perspektywie. */ - if (file_exists(Config::Config()->get_path_www() . "/js/page_corpus_{$subpage}.js")){ + if (file_exists(Config::Cfg()->get_path_www() . "/js/page_corpus_{$subpage}.js")){ $this->includeJs("js/page_corpus_{$subpage}.js"); } - if (file_exists(Config::Config()->get_path_www() . "/js/page_corpus_{$subpage}_resize.js")){ + if (file_exists(Config::Cfg()->get_path_www() . "/js/page_corpus_{$subpage}_resize.js")){ $this->includeJs("js/page_corpus_{$subpage}_resize.js"); } - if (file_exists(Config::Config()->get_path_www() . "/css/page_corpus_{$subpage}.css")){ + if (file_exists(Config::Cfg()->get_path_www() . "/css/page_corpus_{$subpage}.css")){ $this->includeCss("css/page_corpus_{$subpage}.css"); } diff --git a/engine/page/page_export_download.php b/engine/page/page_export_download.php index 89383c05..a1ee490e 100644 --- a/engine/page/page_export_download.php +++ b/engine/page/page_export_download.php @@ -6,7 +6,7 @@ * See LICENCE */ -require_once(implode(DIRECTORY_SEPARATOR, array(Config::Config()->get_path_engine(), "page", "page_corpus_export.php"))); +require_once(implode(DIRECTORY_SEPARATOR, array(Config::Cfg()->get_path_engine(), "page", "page_corpus_export.php"))); class Page_export_download extends CPage{ diff --git a/engine/page/page_home.php b/engine/page/page_home.php index d9e14d46..e721ab1a 100644 --- a/engine/page/page_home.php +++ b/engine/page/page_home.php @@ -17,7 +17,7 @@ function __construct() function execute(){ global $user; - $user_id = isset($user["user_id"]) + $user_id = isset($user["user_id"]) ? intval($user["user_id"]) : null ; diff --git a/engine/page/page_ner.php b/engine/page/page_ner.php index 655e8e91..9ea7d3c9 100644 --- a/engine/page/page_ner.php +++ b/engine/page/page_ner.php @@ -16,7 +16,7 @@ function __construct(){ function execute(){ - $this->set('models', Config::Config()->get_liner2_api()); + $this->set('models', Config::Cfg()->get_liner2_api()); } } diff --git a/engine/page/page_report.php b/engine/page/page_report.php index 7153df92..1a4d45b6 100755 --- a/engine/page/page_report.php +++ b/engine/page/page_report.php @@ -163,13 +163,13 @@ function execute(){ * js/page_report_{$subpage}_resize.js — kod JS odpowiedzialny za automatyczne dopasowanie okna do strony. * css/page_report_{$subpage}.css — style CSS występujące tylko w danej perspektywie. */ - if (file_exists(Config::Config()->get_path_www() . "/js/page_report_{$subpage}.js")){ + if (file_exists(Config::Cfg()->get_path_www() . "/js/page_report_{$subpage}.js")){ $this->includeJs("js/page_report_{$subpage}.js"); } - if (file_exists(Config::Config()->get_path_www() . "/js/page_report_{$subpage}_resize.js")){ + if (file_exists(Config::Cfg()->get_path_www() . "/js/page_report_{$subpage}_resize.js")){ $this->includeJs("js/page_report_{$subpage}_resize.js"); } - if (file_exists(Config::Config()->get_path_www() . "/css/page_report_{$subpage}.css")){ + if (file_exists(Config::Cfg()->get_path_www() . "/css/page_report_{$subpage}.css")){ $this->includeCss("css/page_report_{$subpage}.css"); } diff --git a/engine/page/page_wccl_match_tester.php b/engine/page/page_wccl_match_tester.php index 94b36222..9b501c49 100644 --- a/engine/page/page_wccl_match_tester.php +++ b/engine/page/page_wccl_match_tester.php @@ -23,7 +23,7 @@ function execute(){ $annotation_types[] = "t3_set"; $annotation_types[] = "t3_range"; - $this->set('corpora', Config::Config()->wccl_match_tester_corpora); + $this->set('corpora', Config::Cfg()->wccl_match_tester_corpora); $this->set('annotation_types', $annotation_types); } } diff --git a/engine/page/report_perspectives/PerspectiveAgreement.php b/engine/page/report_perspectives/PerspectiveAgreement.php index 10ceb999..1887df35 100644 --- a/engine/page/report_perspectives/PerspectiveAgreement.php +++ b/engine/page/report_perspectives/PerspectiveAgreement.php @@ -13,6 +13,7 @@ function __construct(CPage $page, $document) parent::__construct($page, $document); $this->page->includeJs("js/c_widget_annotation_type_tree.js"); $this->page->includeJs("js/c_widget_user_selection_a_b.js"); + $this->page->includeJs("js/page_report_annotation_tree_loader.js"); } function execute(){ diff --git a/engine/page/report_perspectives/PerspectiveAnaphora.php b/engine/page/report_perspectives/PerspectiveAnaphora.php index cde27ef9..06b0dd36 100644 --- a/engine/page/report_perspectives/PerspectiveAnaphora.php +++ b/engine/page/report_perspectives/PerspectiveAnaphora.php @@ -10,7 +10,7 @@ class PerspectiveAnaphora extends CPerspective { function execute() { - $document_id = $this->document[id]; + $document_id = $this->document['id']; $rows = $this->page->getDb()->fetch_rows("SELECT ans.from AS ans_from, ans.to AS ans_to, ans.type AS ans_type, ans.text AS ans_text," . " ant.from AS ant_from, ant.to AS ant_to, ant.type AS ant_type, ant.text AS ant_text," . @@ -45,43 +45,44 @@ function load_document_content($relations){ $htmlStr = new HtmlStr($this->document['content']); foreach ($relations as $ann){ - if ( !isset($elements[$ann[target_id]]) ){ + if ( !isset($elements[$ann['target_id']]) ){ $annotation = sprintf("", $ann['target_id'], $ann['ant_type']); - $elements[$ann[target_id]] = array("annotation"=>$annotation, + $elements[$ann['target_id']] = array("annotation"=>$annotation, "from"=>$ann['ant_from'], "to"=>$ann['ant_to'], "before"=>"", "after"=>array()); $element_id = $next_id++; - $index[$ann[target_id]] = $element_id; + $index[$ann['target_id']] = $element_id; $sup = "<#$element_id>"; - $elements[$ann[target_id]][before] = $sup; + $elements[$ann['target_id']]['before'] = $sup; } } foreach ($relations as $ann){ - $element_id = $index[$ann[target_id]]; + $element_id = $index[$ann['target_id']]; $sup = "<#↦$element_id>"; - if ( !isset($elements[$ann[source_id]]) ){ + if ( !isset($elements[$ann['source_id']]) ){ $annotation = sprintf("", $ann['source_id'], $ann['ans_type']); - $elements[$ann[source_id]] = array("annotation"=>$annotation, + $elements[$ann['source_id']] = array("annotation"=>$annotation, "from"=>$ann['ans_from'], "to"=>$ann['ans_to'], "before"=>"", "after"=>array()); } - $elements[$ann[source_id]][after][] = $sup; + $elements[$ann['source_id']]['after'][] = $sup; } foreach ($elements as $id=>$e){ - $htmlStr->insertTag($e['from'], $e[before].$e[annotation], $e['to']+1, "" . implode($e[after])); + $htmlStr->insertTag($e['from'], $e['before'].$e['annotation'], $e['to']+1, "" . implode($e['after'])); } }catch (Exception $ex){ + //TODO Check what is this handler custom_exception_handler($ex); } diff --git a/engine/page/report_perspectives/PerspectiveAnnotation_attributes.php b/engine/page/report_perspectives/PerspectiveAnnotation_attributes.php index e4d54da1..a9fc058d 100644 --- a/engine/page/report_perspectives/PerspectiveAnnotation_attributes.php +++ b/engine/page/report_perspectives/PerspectiveAnnotation_attributes.php @@ -18,6 +18,7 @@ function __construct(CPage $page, $document){ $this->page->includeJs("js/c_widget_annotation_type_tree.js"); $this->page->includeJs("js/c_widget_annotation_details.js"); + $this->page->includeJs("js/page_report_annotation_tree_loader.js"); } function execute(){ diff --git a/engine/page/report_perspectives/PerspectiveAnnotation_lemma.php b/engine/page/report_perspectives/PerspectiveAnnotation_lemma.php index 367d9de9..0fe6e4a1 100644 --- a/engine/page/report_perspectives/PerspectiveAnnotation_lemma.php +++ b/engine/page/report_perspectives/PerspectiveAnnotation_lemma.php @@ -13,6 +13,7 @@ function __construct(CPage $page, $document){ parent::__construct($page, $document); $this->page->includeJs("js/c_annotation_mode.js"); $this->page->includeJs("js/c_widget_annotation_type_tree.js"); + $this->page->includeJs("js/page_report_annotation_tree_loader.js"); } function execute(){ diff --git a/engine/page/report_perspectives/PerspectiveAnnotator.php b/engine/page/report_perspectives/PerspectiveAnnotator.php index 53d584a9..362b6f12 100644 --- a/engine/page/report_perspectives/PerspectiveAnnotator.php +++ b/engine/page/report_perspectives/PerspectiveAnnotator.php @@ -25,6 +25,7 @@ function __construct(CPage $page, $document){ $this->page->includeJs("js/c_autoaccordionview.js"); $this->page->includeJs("js/page_report_preview.js"); $this->page->includeJs("libs/bootstrap-confirmation.min.js"); + $this->page->includeJs("js/page_report_annotation_tree_loader.js"); } function execute(){ @@ -34,11 +35,16 @@ function execute(){ $an_source = null; $anUserIds = null; $annotation_mode = 'final'; - $report = $this->page->report; - $corpusId = $corpus['id']; + $report = isset($this->page->report) ? $this->page->report : null; + $pageCid = isset($this->page->cid) ? $this->page->cid : null; + $pageId = isset($this->page->id) ? $this->page->id : null; + $reportId = isset($report["id"]) ? $report["id"] : ''; + $corpusId = isset($corpus['id']) ? $corpus['id'] : ''; // Init global tables - if (!is_array($this->annotationsClear)){ + if ( !isset($this->annotationsClear) + || !is_array($this->annotationsClear) + ){ $this->annotationsClear = array(); } @@ -88,10 +94,13 @@ function execute(){ $htmlStr = ReportContent::getHtmlStr($report); $annotationTypes = CookieManager::getAnnotationTypeTreeAnnotationTypes($corpusId); - $annotations = DbAnnotation::getReportAnnotations($report['id'], $anUserIds, null, null, $annotationTypes, $anStages); - $relations = DbReportRelation::getReportRelations($this->page->cid, $this->page->id, $relationTypeIds, $annotationTypes, null,null, $annotation_mode); + $annotations = DbAnnotation::getReportAnnotations($reportId, $anUserIds, null, null, $annotationTypes, $anStages); + $relations = DbReportRelation::getReportRelations($pageCid, $pageId, $relationTypeIds, $annotationTypes, null,null, $annotation_mode); $htmlStr = ReportContent::insertAnnotationsWithRelations($htmlStr, $annotations, $relations); - $htmlStr = ReportContent::insertTokens($htmlStr, DbToken::getTokenByReportId($report[DB_COLUMN_REPORTS__REPORT_ID])); + $reportIdColumn = isset($report[DB_COLUMN_REPORTS__REPORT_ID]) + ? $report[DB_COLUMN_REPORTS__REPORT_ID] + : ''; + $htmlStr = ReportContent::insertTokens($htmlStr, DbToken::getTokenByReportId($reportIdColumn)); $annotation_sets = DbAnnotation::getAnnotationStructureByCorpora($corpusId); @@ -107,7 +116,9 @@ function execute(){ /* Setup active accordion panel */ $accordions = array("collapseConfiguration", "collapsePad", "collapseAnnotations", "collapseRelations"); - $activeAccordion = $_COOKIE['accordion_active']; + $activeAccordion = isset($_COOKIE['accordion_active']) + ? $_COOKIE['accordion_active'] + : ''; if ( !in_array($activeAccordion, $accordions) ){ $activeAccordion = $accordions[0]; } @@ -136,7 +147,7 @@ function set_panels(){ * */ function set_annotation_menu(){ - global $db, $user; + global $user; //Find out which annotation types are selected in view configuration $selected_annotation_types = CookieManager::getSelectedAnnotationTypeTreeAnnotationTypes($this->document['corpora']); @@ -156,10 +167,13 @@ function set_annotation_menu(){ " LEFT JOIN annotation_subsets ss USING (annotation_subset_id)" . " WHERE (c.corpus_id = {$this->document['corpora']} AND t.group_id IN ({$selected_types_string}))" . " ORDER BY `set`, subset, t.name"; - $annotation_types = $db->fetch_rows($sql); + $annotation_types = $this->page->getDb()->fetch_rows($sql); $sql = "SELECT * FROM annotation_types_shortlist ats WHERE ats.user_id = ?"; - $user_preferences = $db->fetch_rows($sql, array($user['user_id'])); + + $user_preferences = isset($user['user_id']) + ? $this->page->getDb()->fetch_rows($sql, array($user['user_id'])) + : array() ; // no preferences in DB //Find out if user changed the visibility of any annotations @@ -206,10 +220,12 @@ function set_annotation_menu(){ $annotation_grouped[$set][$set_name][$subset]['notcommon'] = !$an['common']; $annotationsSubsets[] = $an['subsetid']; } - $annotation_grouped[$set][$set_name][$subset][$an[name]] = $an; + $annotation_grouped[$set][$set_name][$subset][$an['name']] = $an; $annotation_grouped[$set][$set_name][$subset]['notcommon'] |= !$an['common']; } - if (!$_COOKIE['clearedLayer']){ + if ( !isset($_COOKIE['clearedLayer']) + || !$_COOKIE['clearedLayer'] + ){ setcookie('clearedLayer', '{"id'.implode('":1,"id', $this->annotationsClear).'":1}'); setcookie('clearedSublayer', '{"id'.implode('":1,"id', $annotationsSubsets).'":1}'); } @@ -220,11 +236,13 @@ function set_annotation_menu(){ */ function set_events(){ /*****obsluga zdarzeń********/ + $pageCid = isset($this->page->cid) ? $this->page->cid : null; + $pageId = isset($this->page->id) ? $this->page->id : null; //lista dostepnych grup zdarzen dla danego korpusu $sql = "SELECT DISTINCT event_groups.event_group_id, event_groups.name " . "FROM corpus_event_groups " . "JOIN event_groups " . - "ON (corpus_event_groups.corpus_id={$this->page->cid} AND corpus_event_groups.event_group_id=event_groups.event_group_id) " . + "ON (corpus_event_groups.corpus_id={$pageCid} AND corpus_event_groups.event_group_id=event_groups.event_group_id) " . "JOIN event_types " . "ON (event_groups.event_group_id=event_types.event_group_id)"; $event_groups = $this->page->getDb()->fetch_rows($sql); @@ -237,7 +255,7 @@ function set_events(){ "count(reports_events_slots.report_event_slot_id) AS slots " . "FROM reports_events " . "JOIN reports " . - "ON (reports_events.report_id={$this->page->id} " . + "ON (reports_events.report_id={$pageId} " . "AND reports_events.report_event_id=reports.id) " . "JOIN event_types " . "ON (reports_events.event_type_id=event_types.event_type_id) " . diff --git a/engine/page/report_perspectives/PerspectiveAnnotator_anaphora.php b/engine/page/report_perspectives/PerspectiveAnnotator_anaphora.php index bee08f1b..1787c9af 100644 --- a/engine/page/report_perspectives/PerspectiveAnnotator_anaphora.php +++ b/engine/page/report_perspectives/PerspectiveAnnotator_anaphora.php @@ -180,10 +180,10 @@ function set_annotations(){ $relations = $this->page->getDb()->fetch_rows($sql_relations, array($id)); foreach ($relations as $r){ - if ($r[group_id] == 1) - $htmlStr2->insert($r[to]+1, "", false, true, false); + if ($r['group_id'] == 1) + $htmlStr2->insert($r['to']+1, "", false, true, false); else - $htmlStr->insert($r[to]+1, "", false, true, false); + $htmlStr->insert($r['to']+1, "", false, true, false); } $this->page->set('content_inline', Reformat::xmlToHtml($htmlStr->getContent())); diff --git a/engine/page/report_perspectives/PerspectiveEdit.php b/engine/page/report_perspectives/PerspectiveEdit.php index 2102419c..7c3155b4 100644 --- a/engine/page/report_perspectives/PerspectiveEdit.php +++ b/engine/page/report_perspectives/PerspectiveEdit.php @@ -23,7 +23,7 @@ function set_dropdown_lists() $select_format = DbReport::getAllFormatsByName(); $sql = "SELECT COUNT(*) FROM reports_annotations WHERE report_id = ?"; - $annotations_count = $this->page->getDb()->fetch_one($sql, $this->document[id]); + $annotations_count = $this->page->getDb()->fetch_one($sql, $this->document['id']); try{ $content = $this->document['content']; diff --git a/engine/page/report_perspectives/PerspectivePreview.php b/engine/page/report_perspectives/PerspectivePreview.php index 0a6bfefc..b8f66df3 100644 --- a/engine/page/report_perspectives/PerspectivePreview.php +++ b/engine/page/report_perspectives/PerspectivePreview.php @@ -14,6 +14,7 @@ function __construct(CPage $page, $document) $this->page->includeJs("js/c_widget_annotation_type_tree.js"); $this->page->includeJs("js/c_widget_relation_sets.js"); $this->page->includeJs("js/c_autoaccordionview.js"); + $this->page->includeJs("js/page_report_annotation_tree_loader.js"); } function execute() @@ -71,7 +72,8 @@ function execute() $this->page->set("stage_relations", $stage_relations); $this->page->set("stages_annotations", $stages_annotations); $this->page->set("stages_relations", $stages_relations); - $this->page->set('annotation_types', DbAnnotation::getAnnotationStructureByCorpora($corpusId)); + $this->page->set('annotation_types', DbAnnotation::getAnnotationStructureByCorpora($corpusId,True)); + $this->page->set('annotation_types_threshold_name',MAX_TYPES_NAME_LABEL); $this->page->set('relation_sets', DbRelationSet::getRelationSetsAssignedToCorpus($corpusId)); $this->page->set("annotations", $annotations); $this->page->set("relations", $relations); diff --git a/engine/page/report_perspectives/PerspectiveRelation_agreement.php b/engine/page/report_perspectives/PerspectiveRelation_agreement.php index a469668b..c885fffe 100644 --- a/engine/page/report_perspectives/PerspectiveRelation_agreement.php +++ b/engine/page/report_perspectives/PerspectiveRelation_agreement.php @@ -13,6 +13,7 @@ function __construct(CPage $page, $document){ $this->page->includeJs("js/c_widget_relation_type_tree.js"); $this->page->includeJs("js/c_widget_annotation_type_tree.js"); $this->page->includeJs("js/c_widget_user_selection_a_b.js"); + $this->page->includeJs("js/page_report_annotation_tree_loader.js"); } function execute(){ diff --git a/engine/settings.php b/engine/settings.php index b4e8608c..98f37f53 100644 --- a/engine/settings.php +++ b/engine/settings.php @@ -14,7 +14,13 @@ ini_set("display_errors", 1); ini_set("output_buffering", 0); ini_set("short_open_tag",1); -setlocale(LC_CTYPE, "en_US.UTF-8"); +setlocale(LC_CTYPE, "en_US.UTF-8"); - +require_once(__DIR__ . DIRECTORY_SEPARATOR . 'include.php'); + +set_error_handler("ErrorService::errorHandler"); +/*if(! PHPUnitTools::isPHPUnitRunning()) { + // under PHPUnit this one not works + register_shutdown_function("ErrorService::shutdownFunction"); +}*/ ?> diff --git a/engine/templates/inc_footer.tpl b/engine/templates/inc_footer.tpl index e6825c7a..60b2de84 100644 --- a/engine/templates/inc_footer.tpl +++ b/engine/templates/inc_footer.tpl @@ -10,27 +10,25 @@ {if $Config.federationLoginUrl} {*inclusion of clarin bar*} - {literal} - {/literal} {/if} {if $Config.log_sql} -
Warning: SQL logging is ON. To disable it set Config::Config()->put_log_sql(false); in config.local.php.
+
Warning: SQL logging is ON. To disable it set Config::Cfg()->put_log_sql(false); in config.local.php.
{/if}
diff --git a/engine/templates/inc_header.tpl b/engine/templates/inc_header.tpl index bd96ae39..11e159a1 100644 --- a/engine/templates/inc_header.tpl +++ b/engine/templates/inc_header.tpl @@ -62,8 +62,8 @@ - - + + @@ -161,7 +161,7 @@ {/if}
@@ -202,4 +202,3 @@

{/if} - diff --git a/engine/templates/inc_header2.tpl b/engine/templates/inc_header2.tpl index 91e146a3..d7daaf52 100644 --- a/engine/templates/inc_header2.tpl +++ b/engine/templates/inc_header2.tpl @@ -66,7 +66,7 @@ - {if $page==wccl_match_tester || $page==corpus_wccl_match} + {if $page=="wccl_match_tester" || $page=="corpus_wccl_match"} @@ -93,10 +93,13 @@ {foreach from=$include_files item=f} - {if $f.type == "js"}{* - *}{elseif $f.type == "css"}{/if} +{if $f.type == "js"} + +{elseif $f.type == "css"} + +{/if} {/foreach} - +
diff --git a/engine/templates/inc_menu2.tpl b/engine/templates/inc_menu2.tpl index cf46dc87..62abd5da 100644 --- a/engine/templates/inc_menu2.tpl +++ b/engine/templates/inc_menu2.tpl @@ -15,10 +15,10 @@
  • Corpora
  • - {if isset($corpus.id)} + {if isset($corpus.id)} {/if} - {if isset($corpus.id) && ( "read"|has_corpus_role_or_owner || "admin"|has_role || !empty($corpus.public) ) } + {if isset($corpus.id) && ( "read"|has_corpus_role_or_owner || "admin"|has_role || !empty($corpus.public) ) }
    -{literal} -{/literal} diff --git a/engine/templates/inc_report_morphodisamb.tpl b/engine/templates/inc_report_morphodisamb.tpl index cd2e3ffd..871b0981 100644 --- a/engine/templates/inc_report_morphodisamb.tpl +++ b/engine/templates/inc_report_morphodisamb.tpl @@ -149,11 +149,9 @@ -{literal} -{/literal} diff --git a/engine/templates/inc_report_morphodisambagreement.tpl b/engine/templates/inc_report_morphodisambagreement.tpl index 66639777..b266a46d 100644 --- a/engine/templates/inc_report_morphodisambagreement.tpl +++ b/engine/templates/inc_report_morphodisambagreement.tpl @@ -136,21 +136,18 @@ diff --git a/engine/templates/inc_system_messages.tpl b/engine/templates/inc_system_messages.tpl index 20ed8204..e011d995 100644 --- a/engine/templates/inc_system_messages.tpl +++ b/engine/templates/inc_system_messages.tpl @@ -6,28 +6,28 @@ *} {* Komunikaty systemowe *} -{if $action_permission_denied} +{if isset($action_permission_denied)}
    Access denied:
    {$action_permission_denied}
    {/if} -{if $action_error} +{if isset($action_error)}
    Error:
    {$action_error}
    {/if} -{if $action_performed} +{if isset($action_performed)}
    Success:
    {$action_performed}
    {/if} -{if $page_permission_denied} +{if isset($page_permission_denied)}
    Access denied:
    »{$page_permission_denied}
    diff --git a/engine/templates/inc_widget_annotation_type_tree.tpl b/engine/templates/inc_widget_annotation_type_tree.tpl index 04aceb14..65d1f068 100644 --- a/engine/templates/inc_widget_annotation_type_tree.tpl +++ b/engine/templates/inc_widget_annotation_type_tree.tpl @@ -14,54 +14,14 @@ Display - - {foreach from=$annotation_types item=set key=k name=groups} - - - - - {$set.name} - - - - - - {foreach from=$set item=subset key=sk name=subsets} - {if $sk != "name"} - - - - - - {$subset.name} - - - - - - {foreach from=$subset item=type key=tk name=types} - {if $tk != "name"} - - - - - {$type} - - - - - - {/if} - {/foreach} - {/if} - {/foreach} - {/foreach} - {if $annotation_types|@count==0} + No layers, subsets nor types to display - {/if} - +
    - \ No newline at end of file + +{include file="inc_widget_annotation_type_tree_set_template.tpl"} +{include file="inc_widget_annotation_type_tree_subset_template.tpl"} +{include file="inc_widget_annotation_type_tree_types_template.tpl"} diff --git a/engine/templates/inc_widget_annotation_type_tree_set_template.tpl b/engine/templates/inc_widget_annotation_type_tree_set_template.tpl new file mode 100644 index 00000000..6e908f3e --- /dev/null +++ b/engine/templates/inc_widget_annotation_type_tree_set_template.tpl @@ -0,0 +1,25 @@ +{* + * Part of the Inforex project + * Copyright (C) 2013 Michał Marcińczuk, Jan Kocoń, Marcin Ptak + * Wrocław University of Technology + * See LICENCE + *} +{* HTML template to generate dynamically row for annotation types set row + setRowTpl + Parameters to set in each row by JS code: + setRowId - set in checkbox.name as "layerId-".setRowId + - not originally set in place of group.id ?!? + setRowName - set as content in .layerName element +*} + diff --git a/engine/templates/inc_widget_annotation_type_tree_subset_template.tpl b/engine/templates/inc_widget_annotation_type_tree_subset_template.tpl new file mode 100644 index 00000000..23fc6da2 --- /dev/null +++ b/engine/templates/inc_widget_annotation_type_tree_subset_template.tpl @@ -0,0 +1,26 @@ +{* + * Part of the Inforex project + * Copyright (C) 2013 Michał Marcińczuk, Jan Kocoń, Marcin Ptak + * Wrocław University of Technology + * See LICENCE + *} +{* HTML template to generate dynamically row for annotation types subset row + subsetRowTpl + Parameters to set in each row by JS code: + subsetRowId - set checkboxa.name as "subsetId-".subsetRowId + - set subsetid attr in tr tag .sublayerRow + setRowName - set as content in .layerName element +*} + diff --git a/engine/templates/inc_widget_annotation_type_tree_types_template.tpl b/engine/templates/inc_widget_annotation_type_tree_types_template.tpl new file mode 100644 index 00000000..a0a0f7bd --- /dev/null +++ b/engine/templates/inc_widget_annotation_type_tree_types_template.tpl @@ -0,0 +1,25 @@ +{* + * Part of the Inforex project + * Copyright (C) 2013 Michał Marcińczuk, Jan Kocoń, Marcin Ptak + * Wrocław University of Technology + * See LICENCE + *} +{* HTML template to generate dynamically row for annotation type row + typeRowTpl + Parameters to set in each row by JS code: + typeRowId - set checkboxa.name as "typeId-".typeRowId + - set typeid attr in tr tag .typelayerRow + typeRowName - set as content in .layerName element +*} + diff --git a/engine/templates/inc_widget_relation_type_tree.tpl b/engine/templates/inc_widget_relation_type_tree.tpl index 4e371191..d11e472b 100644 --- a/engine/templates/inc_widget_relation_type_tree.tpl +++ b/engine/templates/inc_widget_relation_type_tree.tpl @@ -45,7 +45,7 @@ {/if} {/foreach} {/foreach} - {if $relation_types|@count==0} + {if (!is_array($relation_types)) || $relation_types|@count==0} No layers or types to display @@ -53,4 +53,4 @@ - \ No newline at end of file + diff --git a/engine/templates/page_administration_annotation_shared_attributes.tpl b/engine/templates/page_administration_annotation_shared_attributes.tpl index ade7b528..e520ea94 100644 --- a/engine/templates/page_administration_annotation_shared_attributes.tpl +++ b/engine/templates/page_administration_annotation_shared_attributes.tpl @@ -25,6 +25,7 @@ + {if isset($sharedAttributes)} {foreach from=$sharedAttributes item=shared_attribute} {$shared_attribute.id} @@ -33,6 +34,7 @@ {$shared_attribute.description} {/foreach} + {/if} @@ -209,4 +211,4 @@ -{include file="inc_footer.tpl"} \ No newline at end of file +{include file="inc_footer.tpl"} diff --git a/engine/templates/page_ccl_viewer.tpl b/engine/templates/page_ccl_viewer.tpl index 6150a543..ffca0bad 100644 --- a/engine/templates/page_ccl_viewer.tpl +++ b/engine/templates/page_ccl_viewer.tpl @@ -15,7 +15,7 @@
    -
    {$content_inline|format_annotations}
    +
    {if isset($content_inline)}{$content_inline|format_annotations}{/if}
    {$content_inline2|format_annotations}
    @@ -37,4 +37,4 @@
    -{include file="inc_footer.tpl"} \ No newline at end of file +{include file="inc_footer.tpl"} diff --git a/engine/templates/page_corpus_agreement_morphology.tpl b/engine/templates/page_corpus_agreement_morphology.tpl index cb3674ed..6ae171fa 100644 --- a/engine/templates/page_corpus_agreement_morphology.tpl +++ b/engine/templates/page_corpus_agreement_morphology.tpl @@ -149,37 +149,36 @@
    -{literal} -{/literal} -{include file="inc_footer.tpl"} \ No newline at end of file +{include file="inc_footer.tpl"} diff --git a/engine/templates/page_corpus_agreement_relations.tpl b/engine/templates/page_corpus_agreement_relations.tpl index 13600d21..fbaade39 100644 --- a/engine/templates/page_corpus_agreement_relations.tpl +++ b/engine/templates/page_corpus_agreement_relations.tpl @@ -178,36 +178,73 @@ -
    -
    Agreement
    -
    -
    - - - - - - - - - {foreach from=$pcs key=category item=data} - - - - - - - - {/foreach} -
    Relation categoryOnly AA and BOnly BPCS
    {$data.name} - {$data.only_a}{$data.a_and_b}{$data.only_b}{$data.pcs|number_format:0}%
    -
    -
    -
    - - - - +
    +
    Users
    +
    + + {if (!is_array($annotators)) || $annotators|@count == 0} + {capture assign=message} + There are no users with agreement annotations for the selected criteria. + {/capture} + {include file="common_message.tpl"} + {else} + + + + + + + + {foreach from=$annotators item=a} + + + + + + + + {/foreach} +
    Annotator nameRels*DocsAB
    {$a.screename}{$a.relation_count}{$a.document_count}
    + *Only agreement relations. + {/if} +
    +
    + + + + + +
    +
    Agreement
    +
    +
    + + + + + + + + + {foreach from=$pcs key=category item=data} + + + + + + + + {/foreach} +
    Relation categoryOnly AA and BOnly BPCS
    {$data.name}{$data.only_a}{$data.a_and_b}{$data.only_b}{$data.pcs|number_format:0}%
    +
    +
    +
    + + + + + -{include file="inc_footer.tpl"} \ No newline at end of file +{include file="inc_footer.tpl"} diff --git a/engine/templates/page_corpus_documents.tpl b/engine/templates/page_corpus_documents.tpl index c8036d41..4673994a 100644 --- a/engine/templates/page_corpus_documents.tpl +++ b/engine/templates/page_corpus_documents.tpl @@ -22,19 +22,21 @@ + + + +
    + Blog by nikic. + Find me on GitHub, + StackOverflow + and Twitter. + Learn more about me. +
    +
    +
    +
    + « Back to article overview. +

    Internal value representation in PHP 7 - Part 1

    + + +
    +
    +

    My last article described the improvements to the hashtable implementation that were introduced in PHP 7. This +followup will take a look at the new representation of PHP values in general.

    + +

    Due to the amount of material to cover, the article is split in two parts: This part will describe how the zval (Zend +value) implementation differs between PHP 5 and PHP 7, and also discuss the implementation of references. The second +part will investigate the realization of individual types like strings or objects in more detail.

    + +

    Zvals in PHP 5

    + +

    In PHP 5 the zval struct is defined as follows:

    + +
    typedef struct _zval_struct {
    +    zvalue_value value;
    +    zend_uint refcount__gc;
    +    zend_uchar type;
    +    zend_uchar is_ref__gc;
    +} zval;
    + +

    As you can see, a zval consists of a value, a type and some additional __gc information, which we’ll talk about in +a moment. The value member is a union of different possible values that a zval can store:

    + +
    typedef union _zvalue_value {
    +    long lval;                 // For booleans, integers and resources
    +    double dval;               // For floating point numbers
    +    struct {                   // For strings
    +        char *val;
    +        int len;
    +    } str;
    +    HashTable *ht;             // For arrays
    +    zend_object_value obj;     // For objects
    +    zend_ast *ast;             // For constant expressions
    +} zvalue_value;
    + +

    A C union is a structure in which only one member can be active at a time and those size matches the size of its largest +member. All members of the union will be stored in the same place in memory and will be interpreted differently +depending on which one you access. If you read the lval member of the above union, its value will be interpreted as a +signed integer. If you read the dval member the value will be interpreted as a double-precision floating point +number instead. And so on.

    + +

    To figure out which of these union members is currently in use, the type property of a zval stores a type tag, which +is simply an integer:

    + +
    #define IS_NULL     0      /* Doesn't use value */
    +#define IS_LONG     1      /* Uses lval */
    +#define IS_DOUBLE   2      /* Uses dval */
    +#define IS_BOOL     3      /* Uses lval with values 0 and 1 */
    +#define IS_ARRAY    4      /* Uses ht */
    +#define IS_OBJECT   5      /* Uses obj */
    +#define IS_STRING   6      /* Uses str */
    +#define IS_RESOURCE 7      /* Uses lval, which is the resource ID */
    +
    +/* Special types used for late-binding of constants */
    +#define IS_CONSTANT 8
    +#define IS_CONSTANT_AST 9
    + +

    Reference counting in PHP 5

    + +

    Zvals in PHP 5 are (with a few exceptions) allocated on the heap and PHP needs some way to keep track which zvals are +currently in use and which should be freed. For this purpose reference counting is employed: The refcount__gc member +of the zval structure stores how often a zval is currently “referenced”. For example in $a = $b = 42 the value 42 +is referenced by two variables, so its refcount is 2. If the refcount reaches zero, it means a value is unused and can +be freed.

    + +

    Note that the references that the refcount refers to (how many times a value is currently used) have nothing to do with +PHP references (using &). I will always using the terms “reference” and “PHP reference” to disambiguate both concepts +in the following. For now we’ll ignore PHP references altogether.

    + +

    A concept that is closely related to reference counting is “copy on write”: A zval can only be shared between multiple +users as long as it isn’t modified. In order to change a shared zval it needs to be duplicated (“separated”) and the +modification will happen only on the duplicated zval.

    + +

    Lets look at an example that shows off both copy-on-write and zval destruction:

    + +
    $a = 42;   // $a         -> zval_1(type=IS_LONG, value=42, refcount=1)
    +$b = $a;   // $a, $b     -> zval_1(type=IS_LONG, value=42, refcount=2)
    +$c = $b;   // $a, $b, $c -> zval_1(type=IS_LONG, value=42, refcount=3)
    +
    +// The following line causes a zval separation
    +$a += 1;   // $b, $c -> zval_1(type=IS_LONG, value=42, refcount=2)
    +           // $a     -> zval_2(type=IS_LONG, value=43, refcount=1)
    +
    +unset($b); // $c -> zval_1(type=IS_LONG, value=42, refcount=1)
    +           // $a -> zval_2(type=IS_LONG, value=43, refcount=1)
    +
    +unset($c); // zval_1 is destroyed, because refcount=0
    +           // $a -> zval_2(type=IS_LONG, value=43, refcount=1)
    +
    + +

    Reference counting has one fatal flaw: It is not able to detect and release cyclic references. To handle this PHP uses +an additional cycle collector. Whenever the refcount of a zval is decremented and there is a chance that this +zval is part of a cycle, the zval is written into a “root buffer”. Once this root buffer is full, potential cycles will +be collected using a mark and sweep garbage collection.

    + +

    In order to support this additional cycle collector, the actually used zval structure is the following:

    + +
    typedef struct _zval_gc_info {
    +    zval z;
    +    union {
    +        gc_root_buffer       *buffered;
    +        struct _zval_gc_info *next;
    +    } u;
    +} zval_gc_info;
    + +

    The zval_gc_info structure embeds the normal zval, as well as one additional pointer - note that u is a union, so +this is really just one pointer with two different types it may point to. The buffered pointer is used to store where +in the root buffer this zval is referenced, so that it may be removed from it if it’s destroyed before the cycle +collector runs (which is very likely). next is used when the collector destroys values, but I won’t go into that here.

    + +

    Motivation for change

    + +

    Let’s talk about sizes a bit (all sizes are for 64-bit systems): First of all, the zvalue_value union is 16 bytes +large, because both the str and obj members have that size. The whole zval struct is 24 bytes (due to padding) and +zval_gc_info is 32 bytes. On top of this, allocating the zval on the heap adds another 16 bytes of allocation +overhead. So we end up using 48 bytes per zval - although this zval may be used by multiple places.

    + +

    At this point we can start thinking about the (many) ways in which this zval implementation is inefficient. Consider the +simple case of a zval storing an integer, which by itself is 8 bytes. Additionally the type-tag needs to be stored in +any case, which is a single byte by itself, but due to padding needs another 8 bytes.

    + +

    To these 16 bytes that we really “need” (in first approximation), we add another 16 bytes handling reference counting +and cycle collection and another 16 bytes of allocation overhead. Not to mention that we actually have to perform that +allocation and the subsequent free, both being quite expensive operations.

    + +

    This raises the question: Does a simple integer value really need to be stored as a reference-counted, +cycle-collectible, heap-allocated value? The answer to this question is of course, no, this doesn’t make sense.

    + +

    Here is a summary of the primary problems with the PHP 5 zval implementation:

    + +
      +
    • Zvals (nearly) always require a heap allocation.
    • +
    • Zvals are always reference counted and always have cycle collection information, even in cases where sharing the +value is not worthwhile (an integer) and it can’t form cycles.
    • +
    • Directly refcounting the zvals leads to double refcounting in the case of objects and resources. The reasons behind +this will be explained in the next part.
    • +
    • Some cases involve quite an awesome amount of indirection. For example to access the object stored in a variable, a +total of four pointers need to be dereferenced (which means following a pointer chain of length four). Once again +this will be discussed in the next part.
    • +
    • Directly refcounting the zvals also means that values can only be shared between zvals. For example it’s not possible +to share a string between a zval and hashtable key (without storing the hashtable key as a zval as well).
    • +
    + +

    Zvals in PHP 7

    + +

    And this brings us to the new zval implementation in PHP 7. The fundamental change that was implemented, is that zvals +are no longer individually heap-allocated and no longer store a refcount themselves. Instead any complex values they +may point to (like strings, arrays or objects) will store the refcount themselves. This has the following advantages:

    + +
      +
    • Simple values do not require allocation and don’t use refcounting.
    • +
    • There is no more double refcounting. In the object case, only the refcount in the object is used now.
    • +
    • Because the refcount is now stored in the value itself, the value can be shared independently of the zval structure. +A string can be used both in a zval and a hashtable key.
    • +
    • There is a lot less indirection, i.e. the number of pointers you need to follow to get to a value is lower.
    • +
    + +

    Now lets take a look at how the new zval is defined:

    + +
    struct _zval_struct {
    +    zend_value value;
    +    union {
    +        struct {
    +            ZEND_ENDIAN_LOHI_4(
    +                zend_uchar type,
    +                zend_uchar type_flags,
    +                zend_uchar const_flags,
    +                zend_uchar reserved)
    +        } v;
    +        uint32_t type_info;
    +    } u1;
    +    union {
    +        uint32_t var_flags;
    +        uint32_t next;                 // hash collision chain
    +        uint32_t cache_slot;           // literal cache slot
    +        uint32_t lineno;               // line number (for ast nodes)
    +        uint32_t num_args;             // arguments number for EX(This)
    +        uint32_t fe_pos;               // foreach position
    +        uint32_t fe_iter_idx;          // foreach iterator index
    +    } u2;
    +};
    + +

    The first member stays pretty similar, this is still a value union. The second member is an integer storing type +information, which is further subdivided into individual bytes using a union (you can ignore the ZEND_ENDIAN_LOHI_4 +macro, which just ensures a consistent layout across platforms with different endianness). The important parts of this +substructure are the type (which is similar to what it was before) and the type_flags, which I’ll explain in a +moment.

    + +

    At this point there exists a small problem: The value member is 8 bytes large and due to struct padding adding even a +single byte to that grows the zval size to 16 bytes. However we obviously don’t need 8 bytes just to store a type. This +is why the zval contains the additional u2 union, which remains unused by default, but can be repurposed by the +surrounding code to store 4 bytes of data. The different union members correspond to different usages of this extra data +slot.

    + +

    The value union looks slightly different in PHP 7:

    + +
    typedef union _zend_value {
    +    zend_long         lval;
    +    double            dval;
    +    zend_refcounted  *counted;
    +    zend_string      *str;
    +    zend_array       *arr;
    +    zend_object      *obj;
    +    zend_resource    *res;
    +    zend_reference   *ref;
    +    zend_ast_ref     *ast;
    +
    +    // Ignore these for now, they are special
    +    zval             *zv;
    +    void             *ptr;
    +    zend_class_entry *ce;
    +    zend_function    *func;
    +    struct {
    +        ZEND_ENDIAN_LOHI(
    +            uint32_t w1,
    +            uint32_t w2)
    +    } ww;
    +} zend_value;
    + +

    First of all, note that the value union is now 8 bytes instead of 16. It will only store integers (lval) and doubles +(dval) directly, everything else is a pointer. All the pointer types (apart from those marked as special above) use +refcounting and have a common header defined by zend_refcounted:

    + +
    struct _zend_refcounted {
    +    uint32_t refcount;
    +    union {
    +        struct {
    +            ZEND_ENDIAN_LOHI_3(
    +                zend_uchar    type,
    +                zend_uchar    flags,
    +                uint16_t      gc_info)
    +        } v;
    +        uint32_t type_info;
    +    } u;
    +};
    + +

    Of course the structure contains a refcount. Additionally it contains a type, some flags and gc_info. The type +just duplicates the zval type and allows the GC to distinguish different refcounted structures without storing a zval. +The flags are used for different purposes with different types and will be explained for each type separately in the +next part.

    + +

    The gc_info is the equivalent of the buffered entry in the old zvals. However instead of storing a pointer into the +root buffer it now contains an index into it. Because the root buffer has a fixed size (10000 elements) it is enough to +use a 16 bit number for this instead of a 64 bit pointer. The gc_info info also encodes the “color” of the node, which +is used to mark nodes during collection.

    + +

    Zval memory management

    + +

    I’ve mentioned that zvals are no longer individually heap-allocated. However they obviously still need to be stored +somewhere, so how does this work? While zvals are still mostly part of heap-allocated structures, they are directly +embedded into them. E.g. a hashtable bucket will directly embed a zval instead of storing a pointer to a separate +zval. The compiled variables table of a function or the property table of an object will be zval arrays that are +allocated in one chunk, instead of storing pointers to separate zvals. As such zvals are now usually stored with one +level of indirection less. What was previously a zval* is now a zval.

    + +

    When a zval is used in a new place, previously this meant copying a zval* and incrementing its refcount. Now it means +copying the contents of a zval (ignoring u2) instead and maybe incrementing the refcount of the value it points +to, if said value uses refcounting.

    + +

    How does PHP know whether a value is refcounted? This cannot be determined solely based on the type, because some types +like strings and arrays are not always refcounted. Instead one bit of the zvals type_info member determines whether or +not the zval is refcounted. There are a number of other bits encoding properties of the type:

    + +
    #define IS_TYPE_CONSTANT            (1<<0)   /* special */
    +#define IS_TYPE_IMMUTABLE           (1<<1)   /* special */
    +#define IS_TYPE_REFCOUNTED          (1<<2)
    +#define IS_TYPE_COLLECTABLE         (1<<3)
    +#define IS_TYPE_COPYABLE            (1<<4)
    +#define IS_TYPE_SYMBOLTABLE         (1<<5)   /* special */
    + +

    The three primary properties a type can have are “refcounted”, “collectable” and “copyable”. You already know what +refcounted means. Collectable means that the zval can participate in a cycle. E.g. strings are (often) refcounted, but +there’s no way you can create a cycle with a string in it.

    + +

    Copyability determines whether the value needs to copied when a “duplication” is performed. A duplication is a hard +copy, e.g. if you duplicate a zval that points to an array, this will not simply increase the refcount on the array. +Instead a new and independent copy of the array will be created. However for some types like objects and resources even +a duplication should only increment the refcount - such types are called non-copyable. This matches the passing +semantics of objects and resources (which are, for the record, not passed by reference).

    + +

    The following table shows the different types and what type flags they use. “Simple types” refers to types like integers +or booleans that don’t use a pointer to a separate structure. A column for the “immutable” flag is also present, which +is used to mark immutable arrays and will be discussed in more detail in the next part.

    + +
                    | refcounted | collectable | copyable | immutable
    +----------------+------------+-------------+----------+----------
    +simple types    |            |             |          |
    +string          |      x     |             |     x    |
    +interned string |            |             |          |
    +array           |      x     |      x      |     x    |
    +immutable array |            |             |          |     x
    +object          |      x     |      x      |          |
    +resource        |      x     |             |          |
    +reference       |      x     |             |          |
    +
    + +

    At this point, lets take a look at two examples of how the zval management works in practice. First, an example using +integers based off the PHP 5 example from above:

    + +
    $a = 42;   // $a = zval_1(type=IS_LONG, value=42)
    +
    +$b = $a;   // $a = zval_1(type=IS_LONG, value=42)
    +           // $b = zval_2(type=IS_LONG, value=42)
    +
    +$a += 1;   // $a = zval_1(type=IS_LONG, value=43)
    +           // $b = zval_2(type=IS_LONG, value=42)
    +
    +unset($a); // $a = zval_1(type=IS_UNDEF)
    +           // $b = zval_2(type=IS_LONG, value=42)
    +
    + +

    This is pretty boring. As integers are no longer shared, both variables will use separate zvals. Don’t forget that these +are now embedded rather than allocated, which I try to signify by writing = instead of a -> pointer. Unsetting a +variable will set the type of the corresponding zval to IS_UNDEF. Now consider a more interesting case where a complex +value is involved:

    + +
    $a = [];   // $a = zval_1(type=IS_ARRAY) -> zend_array_1(refcount=1, value=[])
    +
    +$b = $a;   // $a = zval_1(type=IS_ARRAY) -> zend_array_1(refcount=2, value=[])
    +           // $b = zval_2(type=IS_ARRAY) ---^
    +
    +// Zval separation occurs here
    +$a[] = 1   // $a = zval_1(type=IS_ARRAY) -> zend_array_2(refcount=1, value=[1])
    +           // $b = zval_2(type=IS_ARRAY) -> zend_array_1(refcount=1, value=[])
    +
    +unset($a); // $a = zval_1(type=IS_UNDEF) and zend_array_2 is destroyed
    +           // $b = zval_2(type=IS_ARRAY) -> zend_array_1(refcount=1, value=[])
    +
    + +

    Here each variable still has a separate (embedded) zval, but both zvals point to the same (refcounted) zend_array +structure. Once a modification is done the array needs to be duplicated. This case is similar to how things work in PHP +5.

    + +

    Types

    + +

    Lets take a closer look at what types are supported in PHP 7:

    + +
    // regular data types
    +#define IS_UNDEF                    0
    +#define IS_NULL                     1
    +#define IS_FALSE                    2
    +#define IS_TRUE                     3
    +#define IS_LONG                     4
    +#define IS_DOUBLE                   5
    +#define IS_STRING                   6
    +#define IS_ARRAY                    7
    +#define IS_OBJECT                   8
    +#define IS_RESOURCE                 9
    +#define IS_REFERENCE                10
    +
    +// constant expressions
    +#define IS_CONSTANT                 11
    +#define IS_CONSTANT_AST             12
    +
    +// internal types
    +#define IS_INDIRECT                 15
    +#define IS_PTR                      17
    + +

    This list is quite similar to what was used in PHP 5, however there are a few additions:

    + +
      +
    • The IS_UNDEF type is used in places where previously a NULL zval pointer (not to be confused with an IS_NULL +zval) was used. For example, in the refcounting examples above the IS_UNDEF type is set for variables that have +been unset.
    • +
    • The IS_BOOL type has been split into IS_FALSE and IS_TRUE. As such the value of the boolean is now encoded in +the type, which allows the optimization of a number of type-based checks. This change is transparent to userland, +where this is still a single “boolean” type.
    • +
    • PHP references no longer use an is_ref flag on the zval and use a new IS_REFERENCE type instead. How this works +will be described in the next section.
    • +
    • The IS_INDIRECT and IS_PTR types are special internal types.
    • +
    + +

    The IS_LONG type now uses a zend_long value instead of an ordinary C long. The reason behind this is that on 64-bit +Windows (LLP64) a long is only 32-bit wide, so PHP 5 ended up always using 32-bit numbers on Windows. PHP 7 will allow +you to use 64-bit numbers if you’re on an 64-bit operating system, even if that operating system is Windows.

    + +

    Details of the individual zend_refcounted types will be discussed in the next part. For now we’ll only look at the +implementation of PHP references.

    + +

    References

    + +

    PHP 7 uses an entirely different approach to handling PHP & references than PHP 5 (and I can tell you that this change +is one of the largest source of bugs in PHP 7). Lets start by taking a look at how PHP references used to work in PHP 5:

    + +

    Normally, the copy-on-write principle says that before modifying a zval it needs to be separated, in order to make sure +you don’t end up changing the value for every place sharing the zval. This matches by-value passing semantics.

    + +

    For PHP references this does not apply. If a value is a PHP reference, you want it to change for every user of the +value. The is_ref flag that was part of PHP 5 zvals determined whether a value is a PHP reference and as such whether +it required separation before modification. An example:

    + +
    $a = [];  // $a     -> zval_1(type=IS_ARRAY, refcount=1, is_ref=0) -> HashTable_1(value=[])
    +$b =& $a; // $a, $b -> zval_1(type=IS_ARRAY, refcount=2, is_ref=1) -> HashTable_1(value=[])
    +
    +$b[] = 1; // $a = $b = zval_1(type=IS_ARRAY, refcount=2, is_ref=1) -> HashTable_1(value=[1])
    +
    + +

    One significant problem with this design is that it’s not possible to share a value between a variable that’s a PHP +reference and one that isn’t. Consider the following example:

    + +
    $a = [];  // $a         -> zval_1(type=IS_ARRAY, refcount=1, is_ref=0) -> HashTable_1(value=[])
    +$b = $a;  // $a, $b     -> zval_1(type=IS_ARRAY, refcount=2, is_ref=0) -> HashTable_1(value=[])
    +$c = $b   // $a, $b, $c -> zval_1(type=IS_ARRAY, refcount=3, is_ref=0) -> HashTable_1(value=[])
    +
    +$d =& $c; // $a, $b -> zval_1(type=IS_ARRAY, refcount=2, is_ref=0) -> HashTable_1(value=[])
    +          // $c, $d -> zval_1(type=IS_ARRAY, refcount=2, is_ref=1) -> HashTable_2(value=[])
    +          // $d is a reference of $c, but *not* of $a and $b, so the zval needs to be copied
    +          // here. Now we have the same zval once with is_ref=0 and once with is_ref=1.
    +
    +$d[] = 1; // $a, $b -> zval_1(type=IS_ARRAY, refcount=2, is_ref=0) -> HashTable_1(value=[])
    +          // $c, $d -> zval_1(type=IS_ARRAY, refcount=2, is_ref=1) -> HashTable_2(value=[1])
    +          // Because there are two separate zvals $d[] = 1 does not modify $a and $b.
    +
    + +

    This behavior of references is one of the reasons why using references in PHP will usually end up being slower than +using normal values. To give a less-contrived example where this is a problem:

    + +
    $array = range(0, 1000000);
    +$ref =& $array;
    +var_dump(count($array)); // <-- separation occurs here
    +
    + +

    Because count() accepts its value by-value, but $array is a PHP reference, a full copy of the array is done before +passing it off to count(). If $array weren’t a reference, the value would be shared instead.

    + +

    Now, let’s switch to the PHP 7 implementation of PHP references. Because zvals are no longer individually allocated, it +is not possible to use the same approach that PHP 5 used. Instead a new IS_REFERENCE type is added, which uses the +zend_reference structure as its value:

    + +
    struct _zend_reference {
    +    zend_refcounted   gc;
    +    zval              val;
    +};
    + +

    So essentially a zend_reference is simply a refcounted zval. All variables in a reference set will store a zval with +type IS_REFERENCE pointing to the same zend_reference instance. The val zval behaves like any other zval, in +particular it is possible to share a complex value it points to. E.g. an array can be shared between a variable that is +a reference and another that is a value.

    + +

    Lets go through the above code samples again, this time looking at the PHP 7 semantics. For the sake of brevity I will +stop writing the individual zvals of the variables and only show what structure they point to.

    + +
    $a = [];  // $a                                     -> zend_array_1(refcount=1, value=[])
    +$b =& $a; // $a, $b -> zend_reference_1(refcount=2) -> zend_array_1(refcount=1, value=[])
    +
    +$b[] = 1; // $a, $b -> zend_reference_1(refcount=2) -> zend_array_1(refcount=1, value=[1])
    +
    + +

    The by-reference assignment created a new zend_reference. Note that the refcount is 2 on the reference (because two +variables are part of the PHP reference set), but the value itself only has a refcount of 1 (because one +zend_reference structure points to it). Now consider the case where references and non-references are mixed:

    + +
    $a = [];  // $a         -> zend_array_1(refcount=1, value=[])
    +$b = $a;  // $a, $b,    -> zend_array_1(refcount=2, value=[])
    +$c = $b   // $a, $b, $c -> zend_array_1(refcount=3, value=[])
    +
    +$d =& $c; // $a, $b                                 -> zend_array_1(refcount=3, value=[])
    +          // $c, $d -> zend_reference_1(refcount=2) ---^
    +          // Note that all variables share the same zend_array, even though some are
    +          // PHP references and some aren't.
    +
    +$d[] = 1; // $a, $b                                 -> zend_array_1(refcount=2, value=[])
    +          // $c, $d -> zend_reference_1(refcount=2) -> zend_array_2(refcount=1, value=[1])
    +          // Only at this point, once an assignment occurs, the zend_array is duplicated.
    +
    + +

    The important difference to PHP 5 is that all variables were able to share the same array, even though some were PHP +references and some weren’t. Only once some kind of modification is performed the array will be separated. This means +that in PHP 7 it’s safe to pass a large, referenced array to count(), it is not going to be duplicated. References +will still be slower than normal values, because they require allocation of the zend_reference structure (and +indirection through it) and are usually not handled in the fast-path of engine code.

    + +

    Wrapping up

    + +

    To summarize, the primary change that was implemented in PHP 7 is that zvals are no longer individually heap-allocated +and no longer store a refcount themselves. Instead any complex values they may point to (like strings, array or objects) +will store the refcount themselves. This usually leads to less allocations, less indirection and less memory usage.

    + +

    In the second part of this article the remaining complex types will be discussed.

    + + +
    +
    +
    + If you liked this article, you may want to browse my other articles or + follow me on Twitter. +
    +
    + + blog comments powered by Disqus +
    +
    + +
    + + + + diff --git a/phpunit/dynamic/HtmlStrBigParseTest.php b/phpunit/dynamic/HtmlStrBigParseTest.php index f663abf3..076e7551 100644 --- a/phpunit/dynamic/HtmlStrBigParseTest.php +++ b/phpunit/dynamic/HtmlStrBigParseTest.php @@ -5,6 +5,17 @@ final class HtmlStrBigParseTest extends PHPUnit_Framework_TestCase { +/* this tests doesn't work because source HTML text include + * HTML comment + * At now HtmlParser2 class doesn't recognize properly HTML comments + * and expects closed paired tag. + * We must decide how to process HTML comments and implement recognising + * this tags in parser. + * Added test testCanBeCreatedFromValidLocalFileAfterCommentsRemoved() + * which self remove HTML comments in source text - should will be removed + * after solve problem. + * SW 20231228 + private static $testURL = "https://nikic.github.io/2015/05/05/Internal-value-representation-in-PHP-7-part-1.html"; public function testCanBeCreatedFromValidUTF8Html() @@ -21,5 +32,25 @@ public function testCanBeRestoredFromInternalRepresentation() } // testCanBeRestoredFromInternalRepresentation + public function testCanBeCreatedFromValidLocalFile() + { + $fileName = __DIR__."/../data/"."document_testowy.010.html"; + $text = file_get_contents($fileName); + $obj = new HtmlStr2($text); + $this->assertInstanceOf("HtmlStr2",$obj); + + } // testCanBeCreatedFromValidLocalFile() +*/ + public function testCanBeCreatedFromValidLocalFileAfterCommentsRemoved() + { + $fileName = __DIR__."/../data/"."document_testowy.010.html"; + $text = file_get_contents($fileName); + // remove HTML comments + $text = preg_replace('//','',$text); + $obj = new HtmlStr2($text); + $this->assertInstanceOf("HtmlStr2",$obj); + + } // testCanBeCreatedFromValidLocalFileAfterCommentsRemoved() + } ?> diff --git a/phpunit/phpunit_full.warnings.xml b/phpunit/phpunit_full.warnings.xml new file mode 100644 index 00000000..e0513dd1 --- /dev/null +++ b/phpunit/phpunit_full.warnings.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/phpunit/tests/engine/Config/ConfigTest.php b/phpunit/tests/engine/Config/ConfigTest.php new file mode 100644 index 00000000..e2d87d21 --- /dev/null +++ b/phpunit/tests/engine/Config/ConfigTest.php @@ -0,0 +1,146 @@ +assertInstanceOf($classname, $obj, $msg); + + } // test_instanceOf() + + public function test_reinstance() { + + $this->obj = Config::Cfg(); + $magicToken = "ghghdsah"; + $this->obj->property=$magicToken; + $localobj = Config::Cfg(); + $msg = "Config class doesn't preserve static property. May be is not the same instance..."; + $this->assertSame($localobj->property,$magicToken,$msg); + + } // test_reinstance() + + public function test_get() { + + $expectedValue = "gpw"; + $result = Config::Cfg()->get_sid(); + $msg = "Cannot read sid property from config"; + $this->assertSame($expectedValue,$result,$msg); + + // odczyt parametru o wartości null + $expectedValue = null; + $result = Config::Cfg()->get_federationLoginUrl(); + $msg = "Cannot read federationLoginUrl as null from config"; + $this->assertSame($expectedValue,$result,$msg); + + // odczyt nieistniejącego parametru + $propertyName = "jakasnieistniejacanazwaparametru"; + try { + $commandName = "get_".$propertyName; + $result = Config::Cfg()->$commandName(); + // tu dojdzie jeśli nie zrzuci wyjątku + $this->fail("Didn't generate exception on read unexistent property ".$propertyName."from Config"); + } catch ( ConfigException $e ) { + $expectedMessage = "Parameter '".$propertyName."' not defined in the configuration file."; + $msg = "Unproper message for exception in Config get_".$propertyName."()"; + $this->assertSame($e->getMessage(),$expectedMessage,$msg); + } + + } // test_get() + + public function test_put() { + + $expectedValue = "cośtam"; + $propertyName = "takanazwacojejjeszczeniema"; + $commandName = "put_".$propertyName; + Config::Cfg()->$commandName($expectedValue); + $commandName = "get_".$propertyName; + $result = Config::Cfg()->$commandName(); + $msg = "Cannot write ".$propertyName." property to config"; + $this->assertSame($expectedValue,$result,$msg); + + // test zapisu parametru o wartości null + $expectedValue = null; + $propertyName = "zmiennaowartoscinull"; + $commandName = "put_".$propertyName; + Config::Cfg()->$commandName($expectedValue); + $commandName = "get_".$propertyName; + $result = Config::Cfg()->$commandName(); + $msg = "Cannot write ".$propertyName." property as null to config"; + $this->assertSame($expectedValue,$result,$msg); + + } // test_put() + + public function test_update() { + + $expectedValue = "cośtam"; + $propertyName = "takanazwacojejjeszczeniema"; + $commandName = "put_".$propertyName; + Config::Cfg()->$commandName("firstvalue"); + // teraz aktualizacja wartości istniejącego parametru + Config::Cfg()->$commandName($expectedValue); + // i odczyt tego co tam jest aktualnie + $commandName = "get_".$propertyName; + $result = Config::Cfg()->$commandName(); + $msg = "Cannot write ".$propertyName." property from config"; + $this->assertSame($expectedValue,$result,$msg); + + } // test_update() + + public function test_loadConfigFromFile() { + + $virtualDir = org\bovigo\vfs\vfsStream::setup('root',null,[]); + $expectedValue = "cośtam"; + $propertyName = "takanazwacojejjeszczeniema"; + $commandName = "get_".$propertyName; + + // najpierw wg. starego stylu configa + // generate test file + $fileName = $virtualDir->url()."/oldConfigTest.php"; + $configLine = "".$propertyName." = '".$expectedValue."'; ?>"; + file_put_contents($fileName,$configLine); + + // loadOldLocalConfig jest funkcja prywatną klasy Config + // aby sprowokować jej wykonanie nalezy ustawić zmienną + // konfiguracyjną localConfigFilename, na nazwę pliku, + // i wtedy klasa Config próbuje załadować ten plik zaraz po + // ustawieniu zmiennej, najpierw wg. starego stylu, a jeśli + // to skończy się wyjątkiem, to według nowego: + Config::Cfg()->put_localConfigFilename($fileName); + // sprawdzamy, czy parametr został dodany prawidłowo + $result = Config::Cfg()->$commandName(); + $msg = "Error reading old config file ".$fileName; + $this->assertSame($expectedValue,$result,$msg); + + // teraz wg. nowej synataktyki pliku + $expectedValue = "cośinnego"; + $configLine = "put_".$propertyName."('".$expectedValue."'); ?>"; + file_put_contents($fileName,$configLine); + + // wymusza przeładowanie pliku configa + Config::Cfg()->put_localConfigFilename($fileName); + // sprawdzamy, czy parametr został dodany prawidłowo + $result = Config::Cfg()->$commandName(); + $msg = "Error reading old config file ".$fileName; + $this->assertSame($expectedValue,$result,$msg); + + // skasowanie pliku lokalnego configa po teście + //unlink($fileName); // przy wirtualnym filesystemie niepotrzebne + + } // test_loadConfigFromFile() + + public function test_dumpConfigSets() { + + $result=Config::Cfg()->dumpConfigSets(); + //var_dump($result); + $msg = "dumpConfigSets doesn't return array"; + $this->assertTrue(is_array($result),$msg); + + } // test_dumpConfigSets() + +} +?> diff --git a/phpunit/tests/engine/Config/SingletonTest.php b/phpunit/tests/engine/Config/SingletonTest.php new file mode 100644 index 00000000..32f10c54 --- /dev/null +++ b/phpunit/tests/engine/Config/SingletonTest.php @@ -0,0 +1,32 @@ +obj = $classname::getInstance(); + $msg = "creating of ".$classname." class instance failed."; + $this->assertTrue($this->obj instanceof Singleton\Singleton, $msg); + + } // test_instanceOf() + + public function test_reinstance() { + + $this->obj = SingletonShadow::getInstance(); + $magicToken = "ghghdsah"; + $this->obj->property=$magicToken; + $localobj = SingletonShadow::getInstance(); + $msg = "Singleton class doesn't preserve static property. May be is not the same instance..."; + $this->assertSame($localobj->property,$magicToken,$msg); + + } // test_reinstance() + +} +?> diff --git a/phpunit/tests/engine/include/database/CDbAnnotationTest.php b/phpunit/tests/engine/include/database/CDbAnnotationTest.php index e7999c79..be3af6d2 100644 --- a/phpunit/tests/engine/include/database/CDbAnnotationTest.php +++ b/phpunit/tests/engine/include/database/CDbAnnotationTest.php @@ -103,8 +103,7 @@ public function test_getAnnotationsBySets() // all fields from reports_annotations_attributes "annotation_id" =>null, "annotation_attribute_id" =>null, - "value" =>null, - "user_id" =>null, + "attr_user_id" =>null, "prop" =>null // raa.value as prop ); @@ -112,7 +111,7 @@ public function test_getAnnotationsBySets() $oneRowOptimizedAnnotationData ); $dbEmu->setResponse("fetch_rows", -"SELECT *, raa.`value` AS `prop` FROM reports_annotations ra LEFT JOIN annotation_types at ON (ra.type=at.name) LEFT JOIN reports_annotations_attributes raa ON (ra.id=raa.annotation_id) WHERE ( ra.stage = 'final' AND report_id IN (1)) GROUP BY ra.id ORDER BY `from`", +"SELECT ra.*, at.*, raa.annotation_id, raa.annotation_attribute_id, raa.`user_id` AS `attr_user_id`, raa.`value` AS `prop` FROM reports_annotations ra LEFT JOIN annotation_types at ON (ra.type=at.name) LEFT JOIN reports_annotations_attributes raa ON (ra.id=raa.annotation_id) WHERE ( ra.stage = 'final' AND report_id IN (1)) GROUP BY ra.id ORDER BY `from`", $allOptimizedAnnotationData ); @@ -151,7 +150,7 @@ public function test_getAnnotationStructureByCorpora() "SELECT ans.annotation_set_id AS set_id, ans.name AS set_name, ansub.annotation_subset_id AS subset_id, ansub.name AS subset_name, at.name AS type_name, at.annotation_type_id AS type_id FROM annotation_types at LEFT JOIN annotation_subsets ansub ON ansub.annotation_subset_id=at.annotation_subset_id LEFT JOIN annotation_sets ans ON ans.annotation_set_id=at.group_id LEFT JOIN annotation_sets_corpora ac ON ac.annotation_set_id=ans.annotation_set_id WHERE ac.corpus_id = ?", $allReturnedRows ); - $result = DbAnnotation::getAnnotationStructureByCorpora($corpus_id); + $result = DbAnnotation::getAnnotationStructureByCorpora($corpus_id,True); $this->assertTrue(is_array($result)); // returns raw DB response diff --git a/phpunit/tests/engine/include/export/CclExportDocumentTest.php b/phpunit/tests/engine/include/export/CclExportDocumentTest.php new file mode 100644 index 00000000..d64bb043 --- /dev/null +++ b/phpunit/tests/engine/include/export/CclExportDocumentTest.php @@ -0,0 +1,301 @@ +ccl = new CclExportDocument($report, $tokens, $tags_by_tokens); + + } // setUp() + +// function __construct(&$report, &$tokens, &$tags){ + + public function test_constructor_createsValidCclExportDocumentFromNullParameters() { + + $this->assertInstanceOf('CclExportDocument',$this->ccl); + + } // test_constructor_createsValidCclExportDocumentFromNullParameters() + +// function setAnnotationProperties(&$annotation_properties){ + + public function test_setAnnotationProperties_failsFor1stParameterIsNull() { + + $annotation_properties = null; + // reflection test call for access to private elements + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($this->ccl,'setAnnotationProperties'); + $result = $protectedMethod->invokeArgs($this->ccl,array(&$annotation_properties)); + $this->assertFalse($result); + + $annotation_properties = array(); + // reflection test call for access to private elements + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($this->ccl,'setAnnotationProperties'); + $result = $protectedMethod->invokeArgs($this->ccl,array(&$annotation_properties)); + $this->assertFalse($result); + + // this one for non-empty 2nd param calls method on null object... + $annotation_properties = array("id"=>1); + // reflection test call for access to private elements + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($this->ccl,'setAnnotationProperties'); + $result = $protectedMethod->invokeArgs($this->ccl,array(&$annotation_properties)); + //$this->assertFalse($result); + + } // test_setAnnotationProperties_failsFor1stParameterIsNull() + + + public function test_setAnnotationProperties_returnsFalseForEmpty2ndParameter() { + $annotation_properties = null; + // reflection test call for access to private elements + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($this->ccl,'setAnnotationProperties'); + $result = $protectedMethod->invokeArgs($this->ccl,array(&$annotation_properties)); + $this->assertFalse($result); + + $report = null; + $tokens = null; + $tags_by_tokens = null; + // reflection test call for access to private elements + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($this->ccl,'setAnnotationProperties'); + $result = $protectedMethod->invokeArgs($this->ccl,array(&$annotation_properties)); + $this->assertFalse($result); + + $annotation_properties = array(); // empty array as null + // reflection test call for access to private elements + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($this->ccl,'setAnnotationProperties'); + $result = $protectedMethod->invokeArgs($this->ccl,array(&$annotation_properties)); + $this->assertFalse($result); + + } // test_setAnnotationProperties_returnsFalseForEmpty2ndParameter() + + public function test_setAnnotationProperties_silentlyDoNothingIfNoProperTokenInDocument() { + + $type = 1; + $from = 1; $to = 3; + $name = 'nazwa własności'; + $value = 'wartość własności'; + $annotation_property = array( // must have this 5 fields + "type" => $type, + "from" => $from, + "to" => $to, + "name" => $name, + "value" => $value + ); + $annotation_properties = array( $annotation_property ); + + // new document w/o tokens + // no tokens added to document - no action will be proceeded + + // do test + // reflection test call for access to private elements + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($this->ccl,'setAnnotationProperties'); + $result = $protectedMethod->invokeArgs($this->ccl,array(&$annotation_properties)); + // returns null like for good results... + $this->assertNull($result); + // ...but no token with property added exists + $expectedTokensTable = array(); + $this->assertEquals($expectedTokensTable,$this->ccl->tokens); + + } // test_setAnnotationProperties_silentlyDoNothingIfNoProperTokenInDocument() + + public function test_setAnnotationProperties_setPropTableInDocumentToken() { + + $type = 1; + $from = 1; $to = 3; + $name = 'nazwa własności'; + $value = 'wartość własności'; + $annotation_property = array( // must have this 5 fields + "type" => $type, + "from" => $from, + "to" => $to, + "name" => $name, + "value" => $value + ); + $annotation_properties = array( $annotation_property ); + + // document must have valid cclToken for $from to $to chars + $t = new CclToken(); // $t->prop is null here + $t->setFrom($from); $t->setTo($to); + // must have valid document with this token added + // must set token to document to add property for this range + $this->ccl->addToken($t); + + // do test + //$result = $this->ccl->setAnnotationProperties($annotation_properties); + // reflection test call for access to private elements + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($this->ccl,'setAnnotationProperties'); + $result = $protectedMethod->invokeArgs($this->ccl,array(&$annotation_properties)); + // returns null for good results... + $this->assertNull($result); + // added property should be written to token prop table as below + $expectedPropTable = array( + $type.':'.$name => $value + ); + $this->assertEquals($expectedPropTable,$this->ccl->tokens[0]->prop); + + } // test_setAnnotationProperties_setPropTableInDocumentToken() + +// function setAnnotationLemmas(&$annotation_lemmas) + + public function testEmptyLemmasCallsNoAction() { + + $mockCcl = $this->getMockBuilder('CclExportDocument') + ->disableOriginalConstructor() + -> setMethods(['setAnnotationLemma']) + ->getMock(); + // for empty $lemmas there are no internal call + $annotation_lemmas = array(); + $mockCcl->expects($this->never())->method('setAnnotationLemma'); + // result is returned in $mockCcl changes + // reflection test call for access to private elements + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($mockCcl,'setAnnotationLemmas'); + $result = $protectedMethod->invokeArgs($mockCcl,array($annotation_lemmas)); + + + } // testEmptyLemmasCallsNoAction() + + public function testLemmaIsPassedToCclSetMethod() { + + $mockCcl = $this->getMockBuilder(CclExportDocument::class) + ->disableOriginalConstructor() + -> setMethods(['setAnnotationLemma']) + ->getMock(); + // $mockCcl->setAnnotationLemma should be call for each item from + // $lemmas array + $annotation_lemmas = array('element'); + $mockCcl->expects($this->once())->method('setAnnotationLemma')->with('element'); + // reflection test call for access to private elements + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($mockCcl,'setAnnotationLemmas'); + $result = $protectedMethod->invokeArgs($mockCcl,array($annotation_lemmas)); + + } // testLemmaIsPassedToCclSetMethod() + + public function testAddingLemmaToCclIsRepeatedForEachLemma() { + + $mockCcl = $this->getMockBuilder(CclExportDocument::class) + ->disableOriginalConstructor() + -> setMethods(['setAnnotationLemma']) + ->getMock(); + // $mockCcl->setAnnotationLemma should be call for each item from + // $lemmas array + $annotation_lemmas = array('raz','dwa','trzy'); + //$mockCcl->expects($this->at(0))->method('setAnnotationLemma')->with('raz'); + //$mockCcl->expects($this->at(1))->method('setAnnotationLemma')->with('dwa'); + //$mockCcl->expects($this->at(2))->method('setAnnotationLemma')->with('trzy'); + // zachowanie kolejności nie jest tu istotne + $mockCcl->expects($this->exactly(3))->method('setAnnotationLemma'); + // reflection test call for access to private elements + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($mockCcl,'setAnnotationLemmas'); + $result = $protectedMethod->invokeArgs($mockCcl,array($annotation_lemmas)); + + } // testAddingLemmaToCclIsRepeatedForEachLemma() + +// function setAnnotationsAndRelations( &$annotations, &$relations){...} +// modifies $ccl and returns boolean as operation result + + public function testCorrectDataForSetAnnotationAndRelationCallsCclMethods() { + $relations = array( + // continuous type==1 + array( 'relation_type_id'=>1,'source_id'=>1,'target_id'=>2 ), + // normal + array( 'relation_type_id'=>2,'source_id'=>3,'target_id'=>4 ) + ); + $annotations = array( // ids includes all source and targets from above + array( 'id'=>1 ), array( 'id'=>2 ), array( 'id'=>3 ), + array( 'id'=>4 ) + ); + + $mockCcl = $this->getMockBuilder(CclExportDocument::class) + ->disableOriginalConstructor() + -> setMethods(['setAnnotation', 'setContinuousAnnotation2', + 'addError','setRelation']) + -> getMock(); + // call setAnnotation() 2 times for noncontinuous annotations + $mockCcl->expects($this->exactly(2))->method('setAnnotation'); + $mockCcl->expects($this->at(0))->method('setAnnotation')->with($annotations[2]); + $mockCcl->expects($this->at(1))->method('setAnnotation')->with($annotations[3]); + // call setContinuousAnnotation2() once for continuous annotations pair + $mockCcl->expects($this->once())->method('setContinuousAnnotation2')->with($annotations[0],$annotations[1]); + // call setRelation() once for noncontinuous relation only + // parametres are: source and target annotations record + $mockCcl->expects($this->once())->method('setRelation')->with($annotations[2],$annotations[3],$relations[1]); + // no error set is called + $mockCcl->expects($this->never())->method('addError'); + + // reflection test call for acces to private elements + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($mockCcl,'setAnnotationsAndRelations'); + $result = $protectedMethod->invokeArgs($mockCcl,array(&$annotations,&$relations)); + + // returns true + $this->assertTrue($result); + // no errors in $ccl + $this->assertEquals(0,count($this->ccl->errors)); + + } // testCorrectDataForSetAnnotationAndRelationCallsCclMethods() + + public function testSetannotationsandrelationsOnEmptyAnnotationsReturnsFalse() { + + $annotations = array(); + $relations = array(array("key"=>"value")); + // reflection test call for acces to private elements + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($this->ccl,'setAnnotationsAndRelations'); + $result = $protectedMethod->invokeArgs($this->ccl,array(&$annotations,&$relations)); + + $this->assertFalse($result); + // no errors in $ccl + $this->assertEquals(0,count($this->ccl->errors)); + + } // testSetannotationsandrelationsOnEmptyAnnotationsReturnsFalse() + + public function testSetannotationsandrelationsOnAnnotationsWithNoRelationsCallCclsetannotation() { + + $annotation1 = array( "id"=>1, "annotation_id"=>1 ); + $annotations = array( $annotation1 ); + $relations = array(); + + $mockCcl = $this->getMockBuilder(CclExportDocument::class) + ->disableOriginalConstructor() + -> setMethods(['setAnnotation']) + -> getMock(); + $mockCcl->expects($this->once()) + ->method('setAnnotation') + -> with($annotation1); + + // reflection test call for acces to private elements + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($mockCcl,'setAnnotationsAndRelations'); + $result = $protectedMethod->invokeArgs($mockCcl,array(&$annotations,&$relations)); + + $this->assertTrue($result); + // no errors in $ccl + $this->assertEquals(0,count($this->ccl->errors)); + + } // testSetannotationsandrelationsOnAnnotationsWithNoRelationsCallCclsetannotation() + +// public function setCclProperties(&$annotations, &$relations, $lemmas, $attributes ) + + public function testSetcclpropertiesCallsAllPropertySetMethodsOnce() { + + $annotations = array('annotacje'); + $relations = array('relacje'); + $lemmas = array('lematy'); + $attributes = array('atrybuty'); + $mockCcl = $this->getMockBuilder(CclExportDocument::class) + ->disableOriginalConstructor() + -> setMethods(['setAnnotationsAndRelations','setAnnotationLemmas','setAnnotationProperties']) + -> getMock(); + $mockCcl->expects($this->once())->method('setAnnotationsAndRelations') + -> with($annotations,$relations); + $mockCcl->expects($this->once())->method('setAnnotationLemmas') + -> with($lemmas); + $mockCcl->expects($this->once())->method('setAnnotationProperties') + -> with($attributes); + + $mockCcl->setCclProperties($annotations, $relations, $lemmas, $attributes ); + + } // testSetcclpropertiesCallsAllPropertySetMethodsOnce() + +} // CclExportDocumentTest class + +?> diff --git a/phpunit/tests/engine/include/export/CclFactoryTest.php b/phpunit/tests/engine/include/export/CclFactoryTest.php deleted file mode 100644 index 9cef01cc..00000000 --- a/phpunit/tests/engine/include/export/CclFactoryTest.php +++ /dev/null @@ -1,141 +0,0 @@ -assertInstanceOf('CclDocument',$ccl); - - } // test_createFromReportAndTokens_createsValidCclDocumentFromNullParameters() - -/* - function setAnnotationProperties(&$ccl, &$annotation_properties){ -*/ - - public function test_setAnnotationProperties_failsFor1stParameterIsNull() { - $ccl = null; - - $annotation_properties = null; - $result = CclFactory::setAnnotationProperties($ccl,$annotation_properties); - $this->assertFalse($result); - - $annotation_properties = array(); - $result = CclFactory::setAnnotationProperties($ccl,$annotation_properties); - $this->assertFalse($result); - - /* this one for non-empty 2nd param calls method on null object... - $annotation_properties = array("id"=>1); - $result = CclFactory::setAnnotationProperties($ccl,$annotation_properties); - $this->assertFalse($result); - */ - - } // test_setAnnotationProperties_failsFor1stParameterIsNull() - - - public function test_setAnnotationProperties_returnsFalseForEmpty2ndParameter() { - $annotation_properties = null; - - $ccl = null; - $result = CclFactory::setAnnotationProperties($ccl,$annotation_properties); - $this->assertFalse($result); - - $report = null; - $tokens = null; - $tags_by_tokens = null; - $ccl = CclFactory::createFromReportAndTokens($report, $tokens, $tags_by_tokens); - $result = CclFactory::setAnnotationProperties($ccl,$annotation_properties); - $this->assertFalse($result); - - $annotation_properties = array(); // empty array as null - - $ccl = null; - $result = CclFactory::setAnnotationProperties($ccl,$annotation_properties); - $this->assertFalse($result); - - $report = null; - $tokens = null; - $tags_by_tokens = null; - $ccl = CclFactory::createFromReportAndTokens($report, $tokens, $tags_by_tokens); - $result = CclFactory::setAnnotationProperties($ccl,$annotation_properties); - $this->assertFalse($result); - - } // test_setAnnotationProperties_returnsFalseForEmpty2ndParameter() - - public function test_setAnnotationProperties_silentlyDoNothingIfNoProperTokenInDocument() { - - $type = 1; - $from = 1; $to = 3; - $name = 'nazwa własności'; - $value = 'wartość własności'; - $annotation_property = array( // must have this 5 fields - "type" => $type, - "from" => $from, - "to" => $to, - "name" => $name, - "value" => $value - ); - $annotation_properties = array( $annotation_property ); - - // new document w/o tokens - $ccl = new CclDocument(); - // no tokens added to document - no action will be proceeded - - // do test - $result = CclFactory::setAnnotationProperties($ccl,$annotation_properties); - // returns null like for good results... - $this->assertNull($result); - // ...but no token with property added exists - $expectedTokensTable = array(); - $this->assertEquals($expectedTokensTable,$ccl->tokens); - - } // test_setAnnotationProperties_silentlyDoNothingIfNoProperTokenInDocument() - - public function test_setAnnotationProperties_setPropTableInDocumentToken() { - - $type = 1; - $from = 1; $to = 3; - $name = 'nazwa własności'; - $value = 'wartość własności'; - $annotation_property = array( // must have this 5 fields - "type" => $type, - "from" => $from, - "to" => $to, - "name" => $name, - "value" => $value - ); - $annotation_properties = array( $annotation_property ); - - // document must have valid cclToken for $from to $to chars - $t = new CclToken(); // $t->prop is null here - $t->setFrom($from); $t->setTo($to); - // must have valid document with this token added - $ccl = new CclDocument(); - // must set token to document to add property for this range - $ccl->addToken($t); - - // do test - $result = CclFactory::setAnnotationProperties($ccl,$annotation_properties); - // returns null for good results... - $this->assertNull($result); - // added property should be written to token prop table as below - $expectedPropTable = array( - $type.':'.$name => $value - ); - $this->assertEquals($expectedPropTable,$ccl->tokens[0]->prop); - - } // test_setAnnotationProperties_setPropTableInDocumentToken() - -} // class - -?> diff --git a/phpunit/tests/engine/include/export/ConllAndJsonFactoryTest.php b/phpunit/tests/engine/include/export/ConllAndJsonFactoryTest.php new file mode 100644 index 00000000..3e1f2762 --- /dev/null +++ b/phpunit/tests/engine/include/export/ConllAndJsonFactoryTest.php @@ -0,0 +1,782 @@ +virtualDir = org\bovigo\vfs\vfsStream::setup('root',null,[]); + $this->generateFullTestData(); + // protected method to invoke in all tests + $this->protectedMethod = new ReflectionMethod('ConllAndJsonFactory','makeConllAndJsonExportData'); + $this->protectedMethod->setAccessible(True); + + } // setUp() + + private function generateReportTestData($report_id=1234) { + + if(!$this->report_id) { + $this->report_id = $report_id; + } + // $report = DbReport::getReportById($report_id); + // "SELECT * FROM reports WHERE id = $report_id" + // id,corpora,date,title,source,author,content,type, + // status,user_id,subcorpus_id,tokenization,format_id, + // lang,filename,parent_report_id,deleted + $report = array( "id"=>$this->report_id, "corpora"=>12, + "date"=>'1970-01-01', "title"=>'tytuł', "source"=>'źródło', + "author"=>'Autor', + "content"=>'To jest duże okno. Bardzo duże.', "type"=>1, + "status"=>2, "user_id"=>1, "subcorpus_id"=>null, + "tokenization"=>null, "format_id"=>2, "lang"=>'pol', + "filename"=>'plik.txt', "parent_report_id"=>null, + "deleted"=>0 + ); + return $report; + + } // generateReportTestData() + + private function generateTokensTestData($report_id=1234) { + + if(!$this->report_id) { + $this->report_id = $report_id; + } + + $report_id = $this->report_id; + // $tokens = DbToken::getTokenByReportId($report_id, null, true); + // "SELECT * FROM tokens LEFT JOIN orths USING (orth_id) WHERE report_id = ? ORDER BY `from`" + // token_id, report_id, from, to, eos, orth_id, orth + $tokens = array( + ["token_id"=>1, "report_id"=>$report_id, "from"=>0, "to"=>1, "eos"=>0, "orth_id"=>1, "orth"=>'To'], + ["token_id"=>2, "report_id"=>$report_id, "from"=>2, "to"=>5, "eos"=>0, "orth_id"=>2, "orth"=>'jest'], + ["token_id"=>3, "report_id"=>$report_id, "from"=>6, "to"=>9, "eos"=>0, "orth_id"=>3, "orth"=>'duże'], + ["token_id"=>4, "report_id"=>$report_id, "from"=>10, "to"=>13, "eos"=>0, "orth_id"=>4, "orth"=>'okno'], + ["token_id"=>5, "report_id"=>$report_id, "from"=>14, "to"=>14, "eos"=>1, "orth_id"=>5, "orth"=>'.'], + ["token_id"=>6, "report_id"=>$report_id, "from"=>15, "to"=>20, "eos"=>0, "orth_id"=>6, "orth"=>'Bardzo'], + ["token_id"=>7, "report_id"=>$report_id, "from"=>21, "to"=>24, "eos"=>0, "orth_id"=>3, "orth"=>'duże'], + ["token_id"=>8, "report_id"=>$report_id, "from"=>25, "to"=>25, "eos"=>1, "orth_id"=>5, "orth"=>'.'] + ); + + return $tokens; + + } // generateTokensTestData() + + private function getExpectedConllHeader() { + // static header for all CONLL files + return "ORDER_ID\tTOKEN_ID\tORTH\tCTAG\tFROM\tTO\tANN_TAGS\tANN_IDS\tREL_IDS\tREL_TARGET_ANN_IDS\n"; + } // + + private function getExpectedConll() { + // expected Conll pattern for our data and not annotations + $expectedConll = $this->getExpectedConllHeader(); + $expectedConll .= "0\t0\tTo\t\t0\t1\tO\t_\t_\t_\n". + "1\t1\tjest\t\t2\t5\tO\t_\t_\t_\n". + "2\t2\tduże\t\t6\t9\tO\t_\t_\t_\n". + //"2\t2\tduże\t\t6\t9\tB-\t1\t_\t_\n". + //"2\t2\tduże\t\t6\t9\tB-nam_adj\t1\t_\t_\n". + "3\t3\tokno\t\t10\t13\tO\t_\t_\t_\n". + "4\t4\t.\t\t14\t14\tO\t_\t_\t_\n". + "\n". + "5\t0\tBardzo\t\t15\t20\tO\t_\t_\t_\n". + "6\t1\tduże\t\t21\t24\tO\t_\t_\t_\n". + "7\t2\t.\t\t25\t25\tO\t_\t_\t_\n". + "\n"; + return $expectedConll; + } // getExpectedConll() + + private function extractAnntagsFromConllLines($conllStr,$lineNo) { + + // divide to lines + $conllLines = explode("\n",$conllStr); + // line should looks like "2\t2\tduże\t\t6\t9\tO\t_\t_\t_" + $connLineForToken = $conllLines[$lineNo]; + $columns = explode("\t",$connLineForToken); + $annTags = $columns[6]; + return $annTags; + + } // extractAnntagsFromConllLines() + + private function getExpectedEmptyJson() { + + return array( + "chunks" => array( + array() + ), + "relations" => array(), + "annotations" => array() + ); + + } // getExpectedEmptyJson() + + private function getExpectedChunks() { + // returns "chunks" section in expected table for JSON + // for our data without annotations + $chunks = array( + array( + array( + array('order_id' => 0,'token_id' => 0,'orth' => 'To','ctag' => null,'from' => 0,'to' => 1,'annotations' => array(),'relations' => array()), + array('order_id' => 1,'token_id' => 1,'orth' => 'jest','ctag' => null,'from' => 2,'to' => 5,'annotations' => array(),'relations' => array()), + array('order_id' => 2,'token_id' => 2,'orth' => 'duże','ctag' => null,'from' => 6,'to' => 9,'annotations' => array(),'relations' => array()), + array('order_id' => 3,'token_id' => 3,'orth' => 'okno','ctag' => null,'from' => 10,'to' => 13,'annotations' => array(),'relations' => array()), + array('order_id' => 4,'token_id' => 4,'orth' => '.','ctag' => null,'from' => 14,'to' => 14,'annotations' => array(),'relations' => array()) + ), + array( + array('order_id' => 5,'token_id' => 0,'orth' => 'Bardzo','ctag' => null,'from' => 15,'to' => 20,'annotations' => array(),'relations' => array()), + array('order_id' => 6,'token_id' => 1,'orth' => 'duże','ctag' => null,'from' => 21,'to' => 24,'annotations' => array(),'relations' => array()), + array('order_id' => 7,'token_id' => 2,'orth' => '.','ctag' => null,'from' => 25,'to' => 25,'annotations' => array(),'relations' => array()) + ) + ) + ); + return $chunks; + } // getExpectedChunks + + private function generateAnnotation_By_IdTestData( + $annotationExtractorFields=true, + $annotation_idExtractorFields=true, + $annotationsWithLemmaField=true, + $annotationsWithTypeAttributte=true + ) { + + // Depends from extractor type, annotations row have different + // fields: + // Common section: + // 'id','report_id','type_id','from','to','text','user_id','creation_time','stage','source','annotation_subset_id','type','group_id' + // Fields, that exists only for 'annotation' extractor: + // 'login','screename','lemma'( exists always, but may be null if no lemma ) + // Fields that exist for extractors 'annotation_id' or 'annotation_subset_id' : + // 'group','name','description','css','cross_sentence','shortlist' + // Fields that exists only if type attribute is set : + // 'annotation_id','annotation_attribute_id','value','prop' + + + $annotation_id = 1; + // index must match 'id' field + $annotations_by_id = array( + $annotation_id => array( 'id'=>$annotation_id, + // fields, that always exists + // only 'to' changes business logic + 'report_id'=>1,'type_id'=>360,'from'=>6,'to'=>9,'text'=>'duże','user_id'=>1,'creation_time'=>'2022-10-03 08:07:37','stage'=>'final','source'=>'user','annotation_subset_id'=>'52', + // this are always, but from different tables + 'type'=>'nam_adj','group_id'=>1, + ) + + ); + if($annotationExtractorFields) { + // fields, that exists for extractor 'annotation' only + $annotations_by_id[$annotation_id]['login']='admin'; + $annotations_by_id[$annotation_id]['screename']='Inforex Admin'; + } + if($annotation_idExtractorFields) { + // fields, that exists for extractors 'annotation_id' + // and 'annotation_subset_id' only + $annotations_by_id[$annotation_id]['group']=1; + $annotations_by_id[$annotation_id]['name']='nam_adj'; + $annotations_by_id[$annotation_id]['description']='Przymiotnik utworzony od nazwy własnej'; + $annotations_by_id[$annotation_id]['css']='background: lightgreen;'; + $annotations_by_id[$annotation_id]['cross_sentence']='0'; + $annotations_by_id[$annotation_id]['shortlist']='0'; + } + if($annotationsWithLemmaField){ + $annotations_by_id[$annotation_id]['lemma']='lemat dodany do duże'; + } else { + $annotations_by_id[$annotation_id]['lemma']=null; + } + if($annotationsWithTypeAttributte) { + $annotations_by_id[$annotation_id]['annotation_id']=$annotation_id; + $annotations_by_id[$annotation_id]['annotation_attribute_id']=1; + $annotations_by_id[$annotation_id]['value']='valueAtrTypu'; + $annotations_by_id[$annotation_id]['prop']='valueAtrTypu'; + } + + return $annotations_by_id; + + } // generateAnnotation_By_IdTestData() + + private function generateAnnotationsFromAnnotations_By_Id(array $annotations_by_id) { + return array_values($annotations_by_id); + + } // generateAnnotationsFromAnnotations_By_Id + + private function generateRelationsTestData() { + + $relationData = array( + 'report_id' => '1', + 'id' => '1', + 'relation_type_id' => '1', + 'source_id' => '1', + 'target_id' => '2', + 'relation_set_id' => '1', + 'name' => 'test', + 'rsname' => 'test', + ); + $relations = array( $relationData ); + return $relations; + + } // generateRelationsTestData() + + private function generateFullTestData() { + + $this->report_id = 1234; + + // $file_path_without_ext parameter + $this->file_path_without_ext = $this->virtualDir->url()."/test"; + + // $tokens parameter + $this->tokens = $this->generateTokensTestData($this->report_id); + // tak jest ustawiane zawsze w CorpusExporter + $this->tokens_ids = array_column($this->tokens, 'token_id'); + + // $ccl parameter + $this->ccl = $this->generateFullCclData(); + + } // generateFullTestData() + + private function makeMockToken($id,$orth,$lexemes,$from,$to) { + + $mockToken = $this->getMockBuilder(CclToken::class)->getMock(); + $mockToken->id = $id; + $mockToken->orth = $orth; + $mockToken->lexemes = $lexemes; + $mockToken->from = $from; + $mockToken->to = $to; + return $mockToken; + + } // makeMockToken + + private function generateFullCclData() { + + // mocked $ccl argument for empty report + $mockToken11 = $this->makeMockToken(0,"To",array(),0,1); + $mockToken12 = $this->makeMockToken(1,"jest",array(),2,5); + $mockToken13 = $this->makeMockToken(2,"duże",array(),6,9); + $mockToken14 = $this->makeMockToken(3,"okno",array(),10,13); + $mockToken15 = $this->makeMockToken(4,".",array(),14,14); + $mockSentence1 = $this->getMockBuilder(CclSentence::class)->getMock(); + $mockSentence1->tokens = array($mockToken11,$mockToken12,$mockToken13,$mockToken14,$mockToken15); + $mockToken21 = $this->makeMockToken(5,"Bardzo",array(),15,20); + $mockToken22 = $this->makeMockToken(6,"duże",array(),21,24); + $mockToken23 = $this->makeMockToken(7,".",array(),25,25); + $mockSentence2 = $this->getMockBuilder(CclSentence::class)->getMock(); + $mockSentence2->tokens = array($mockToken21,$mockToken22,$mockToken23); + $mockChunk = $this->getMockBuilder(CclChunk::class)->getMock(); + $mockChunk->sentences = array($mockSentence1,$mockSentence2); + $mockCclDocument = $this->getMockBuilder(CclDocument::class)->getMock(); + $mockCclDocument->chunks = array($mockChunk); + return $mockCclDocument; + + } // generateFullCclData() + +// tests + + public function testEmptyReportMakesEmptyDataToWrite() { + + // all empty input data generates minimal export output + // args for call + $tokens = array(); + $relations = array(); + $annotations = array(); + $tokens_ids = array(); + $annotations_by_id = array(); + $lemmas = array(); + // mocked $ccl argument for empty report + $mockChunk = $this->getMockBuilder(CclChunk::class)->getMock(); + $mockChunk->sentences = array(); + $mockCclDocument = $this->getMockBuilder(CclDocument::class)->getMock(); + $mockCclDocument->chunks = array($mockChunk); + $ccl = $mockCclDocument; + + // invoke tested method + list($conll,$json_builder) = $this->protectedMethod->invoke(new ConllAndJsonFactory(),$ccl,$tokens,$relations,$annotations,$tokens_ids,$annotations_by_id,$lemmas); + + // check results + $this->assertEquals($this->getExpectedConllHeader(),$conll); + $this->assertEquals($this->getExpectedEmptyJson(),$json_builder); + + } // testEmptyReportMakesEmptyDataToWrite() + + public function testOneEmptySentenceCclReportMakesLinesWithNoData() { + + // only 1 empty sentence in 1 chunk in Ccl + // args for call + $tokens = array(); + $relations = array(); + $annotations = array(); + $tokens_ids = array(); + $annotations_by_id = array(); + $lemmas = array(); + // mocked $ccl argument for empty report + $mockSentence = $this->getMockBuilder(CclSentence::class)->getMock(); + $mockSentence->tokens = array(); + $mockChunk = $this->getMockBuilder(CclChunk::class)->getMock(); + $mockChunk->sentences = array($mockSentence); + $mockCclDocument = $this->getMockBuilder(CclDocument::class)->getMock(); + $mockCclDocument->chunks = array($mockChunk); + $ccl = $mockCclDocument; + + // invoke tested method + list($conll,$json_builder) = $this->protectedMethod->invoke(new ConllAndJsonFactory(),$ccl,$tokens,$relations,$annotations,$tokens_ids,$annotations_by_id,$lemmas); + + // check results + // empty sentence generates one empty line in export CONLL + $expectedConll = $this->getExpectedConllHeader()."\n"; + $this->assertEquals($expectedConll,$conll); + $expectedJson = $this->getExpectedEmptyJson(); + // empty sentence generates one empty array in export JSON + $expectedJson['chunks'][0][] = array(); + $this->assertEquals($expectedJson,$json_builder); + + } // testOneEmptySentenceCclReportMakesLinesWithNoData() + + public function testOneEmptyTokenCclReportMakesTokenWithEmptyData() { + + // only 1 sentence with 1 empty token in 1 chunk in Ccl + // args for call + $tokens = array(); + $relations = array(); + $annotations = array(); + $tokens_ids = array(); + $annotations_by_id = array(); + $lemmas = array(); + // mocked $ccl argument for empty report + $mockToken = $this->getMockBuilder(CclToken::class)->getMock(); + $mockSentence = $this->getMockBuilder(CclSentence::class)->getMock(); + $mockSentence->tokens = array($mockToken); + $mockChunk = $this->getMockBuilder(CclChunk::class)->getMock(); + $mockChunk->sentences = array($mockSentence); + $mockCclDocument = $this->getMockBuilder(CclDocument::class)->getMock(); + $mockCclDocument->chunks = array($mockChunk); + $ccl = $mockCclDocument; + + // invoke tested method + list($conll,$json_builder) = $this->protectedMethod->invoke(new ConllAndJsonFactory(),$ccl,$tokens,$relations,$annotations,$tokens_ids,$annotations_by_id,$lemmas); + + // check results + // empty token generates row with empty data in export CONLL + $expectedConll = $this->getExpectedConllHeader() + ."\t0\t\t\t\t\tO\t_\t_\t_\n" + ."\n"; + $this->assertEquals($expectedConll,$conll); + // empty token generates one token array in sentence with export + // dummy data in JSON & also creates annotations and relations arrays + $emptyTokenData = array('order_id' => null,'token_id' => 0,'orth' => null,'ctag' => null,'from' => null,'to' => null,'annotations' => Array (),'relations' => Array ()); + $expectedJson['chunks'][0][] = array($emptyTokenData); + // if any token exist, must be annotations & relations tables in JSON + $expectedJson["annotations"] = array(); + $expectedJson["relations"] = array(); + $this->assertEquals($expectedJson,$json_builder); + + } // testOneEmptyTokenCclReportMakesTokenWithEmptyData() + + public function testOneTokenCclMakesNonemptyDataToWrite() { + + // minimal set - 1 sentence with 1 normal token in 1 chunk in Ccl + // args for call + $tokens = array(); + $relations = array(); + $annotations = array(); + $tokens_ids = array(); + $annotations_by_id = array(); + $lemmas = array(); + // mocked $ccl argument for empty report + $mockToken = $this->makeMockToken(0,"To",array(),0,1); + $mockSentence = $this->getMockBuilder(CclSentence::class)->getMock(); + $mockSentence->tokens = array($mockToken); + $mockChunk = $this->getMockBuilder(CclChunk::class)->getMock(); + $mockChunk->sentences = array($mockSentence); + $mockCclDocument = $this->getMockBuilder(CclDocument::class)->getMock(); + $mockCclDocument->chunks = array($mockChunk); + $ccl = $mockCclDocument; + + // invoke tested method + list($conll,$json_builder) = $this->protectedMethod->invoke(new ConllAndJsonFactory(),$ccl,$tokens,$relations,$annotations,$tokens_ids,$annotations_by_id,$lemmas); + + // check results + // simple token generates row with its data in export CONLL + $expectedConll = $this->getExpectedConllHeader() + ."0\t0\tTo\t\t0\t1\tO\t_\t_\t_\n" + ."\n"; + $this->assertEquals($expectedConll,$conll); + // one token generates token array with data in sentence array + // & also creates annotations and relations arrays in export JSON + $emptyTokenData = array('order_id' => 0,'token_id' => 0,'orth' => 'To','ctag' => null,'from' => 0,'to' => 1,'annotations' => Array (),'relations' => Array ()); + $expectedJson['chunks'][0][] = array($emptyTokenData); + // if any token exist, must be annotations & relations tables in JSON + $expectedJson["annotations"] = array(); + $expectedJson["relations"] = array(); + $this->assertEquals($expectedJson,$json_builder); + + } // testOneTokenCclMakesNonemptyDataToWrite() + + public function testAllDataPlacesToDataConllAndJsonStructures() { + + // args for call + $annotations_by_id = $this->generateAnnotation_By_IdTestData(False,True,False,True); + $annotations = $this->generateAnnotationsFromAnnotations_By_Id($annotations_by_id); + $relations = $this->generateRelationsTestData(); + $lemmas = array(); + + // invoke tested method + list($conll,$json_builder) = $this->protectedMethod->invoke(new ConllAndJsonFactory(),$this->ccl,$this->tokens,$relations,$annotations,$this->tokens_ids,$annotations_by_id,$lemmas); + + // check results + $expectedConll = $this->getExpectedConll(); + $expectedConll = str_replace( + "2\t2\tduże\t\t6\t9\tO\t_\t_\t_\n", + "2\t2\tduże\t\t6\t9\tB-nam_adj\t1\t1\t2\n", + $expectedConll); + $this->assertEquals($expectedConll,$conll); + + $expectedChunks = $this->getExpectedChunks(); + // annotation_id to 'annotations' list in 3-rd chunk + $expectedChunks[0][0][2]['annotations'][] = 1; + $expectedChunks[0][0][2]['relations'][0] = 1; + $expectedJson = array( + "chunks" => $expectedChunks, + "relations" => $relations, + "annotations" => array( + array('id'=>1,'report_id'=>1,'type_id'=>360,'from'=>6,'to'=>9, + 'text' => 'duże','user_id' => 1, + 'creation_time' => '2022-10-03 08:07:37','stage' => 'final', + 'source' => 'user','annotation_subset_id' => '52', + 'type'=>'nam_adj','group_id'=>1, + //'login' => 'admin','screename' => 'Inforex Admin', + //'lemma' => 'lemat dodany do duże', + 'group' => 1,'description' => 'Przymiotnik utworzony od nazwy własnej','css' => 'background: lightgreen;','cross_sentence' => '0','shortlist' => '0', + 'name'=>'nam_adj', + // tylko jeśli istnieje atrybut + 'annotation_id' => 1,'annotation_attribute_id' => 1,'value' => 'valueAtrTypu','prop' => 'valueAtrTypu', + // puste lemma + 'lemma' => null + ), + ) + ); + $this->assertEquals($expectedJson,$json_builder); + + } // testAllDataPlacesToDataConllAndJsonStructures() + + public function testDocumentWithoutTokenizationPlaceDataToJsonAndConllArray() { + // CCL is self-tokenized by constructor + // args for call + $tokens = array(); + // tak jest ustawiane zawsze w CorpusExporter + $tokens_ids = array_column($tokens, 'token_id'); + $relations = array(); + $annotations = array(); + $annotations_by_id = array(); + $lemmas = array(); + + // invoke tested method + list($conll,$json_builder) = $this->protectedMethod->invoke(new ConllAndJsonFactory(),$this->ccl,$tokens,$relations,$annotations,$tokens_ids,$annotations_by_id,$lemmas); + + // check results + $this->assertEquals($this->getExpectedConll(),$conll); + + $expectedJson = $this->getExpectedEmptyJson(); + $expectedJson["chunks"] = $this->getExpectedChunks(); + $this->assertEquals($expectedJson,$json_builder); + + // with tokens without annotations there are all the same as above + + // invoke tested method + list($conll,$json_builder) = $this->protectedMethod->invoke(new ConllAndJsonFactory(),$this->ccl,$this->tokens,$relations,$annotations,$this->tokens_ids,$annotations_by_id,$lemmas); + + $this->assertEquals($this->getExpectedConll(),$conll); + $this->assertEquals($expectedJson,$json_builder); + + } // testDocumentWithoutTokenizationPlaceDataToJsonAndConllArray() + + public function testGeneralAnnotationFieldsPlacedToJsonAndConllArray() { + + // are all fields which always should be present in annotation + // record placed correctly to JSON and CONLL structures ? + // args for call without lemma + $annotations_by_id = $this->generateAnnotation_By_IdTestData(); // default annotation with: all extractors fields, lemma & type attribute + $annotations = $this->generateAnnotationsFromAnnotations_By_Id($annotations_by_id); + $relations = $this->generateRelationsTestData(); + $lemmas = array(); + + // invoke tested method + list($conll,$json_builder) = $this->protectedMethod->invoke(new ConllAndJsonFactory(),$this->ccl,$this->tokens,$relations,$annotations,$this->tokens_ids,$annotations_by_id,$lemmas); + + // check results + $expectedConll = $this->getExpectedConll(); + $expectedConll = str_replace( + "2\t2\tduże\t\t6\t9\tO\t_\t_\t_\n", + "2\t2\tduże\t\t6\t9\tB-nam_adj\t1\t1\t2\n", + $expectedConll); + $this->assertEquals($expectedConll,$conll); + + $expectedChunks = $this->getExpectedChunks(); + // annotation_id to 'annotations' list in 3-rd chunk + $expectedChunks[0][0][2]['annotations'][] = 1; + $expectedChunks[0][0][2]['relations'][0] = 1; + $expectedJson = array( + "chunks" => $expectedChunks, + "relations" => $relations, + "annotations" => array( + array('id'=>1,'report_id'=>1,'type_id'=>360,'from'=>6,'to'=>9, + 'text' => 'duże','user_id' => 1, + 'creation_time' => '2022-10-03 08:07:37','stage' => 'final', + 'source' => 'user','annotation_subset_id' => '52', + 'type'=>'nam_adj','group_id'=>1, + // 'annotation' extractor group + 'login' => 'admin','screename' => 'Inforex Admin', + 'lemma' => 'lemat dodany do duże', + // end of 'annotation' extractor group +// these fields shows only for annotationExtractor = false + 'group' => 1,'description' => 'Przymiotnik utworzony od nazwy własnej','css' => 'background: lightgreen;','cross_sentence' => '0','shortlist' => '0', + 'name'=>'nam_adj', + // tylko jeśli istnieje atrybut + 'annotation_id' => 1,'annotation_attribute_id' => 1,'value' => 'valueAtrTypu','prop' => 'valueAtrTypu' + ), + ) + ); + $this->assertEquals($expectedJson,$json_builder); + + } // testGeneralAnnotationFieldsPlacedToJsonAndConllArray + + public function testLemmaAdsNotChangesConll() { + + $relations = $this->generateRelationsTestData(); + $lemmas = array(); + // args for call without lemma + $LemmaExists = False; + $annotations_by_id = $this->generateAnnotation_By_IdTestData(True,True,$LemmaExists); + $annotations = $this->generateAnnotationsFromAnnotations_By_Id($annotations_by_id); + // invoke tested method + list($conll,$json_builder) = $this->protectedMethod->invoke(new ConllAndJsonFactory(),$this->ccl,$this->tokens,$relations,$annotations,$this->tokens_ids,$annotations_by_id,$lemmas); + + // args for call with lemma + $LemmaExists = True; + $annotations_by_id = $this->generateAnnotation_By_IdTestData(True,True,$LemmaExists); + $annotations = $this->generateAnnotationsFromAnnotations_By_Id($annotations_by_id); + // invoke tested method + list($conll_wL,$json_builder_wL) = $this->protectedMethod->invoke(new ConllAndJsonFactory(),$this->ccl,$this->tokens,$relations,$annotations,$this->tokens_ids,$annotations_by_id,$lemmas); + + // conll not changed after add lemma: + $this->assertEquals($conll,$conll_wL); + + } // testLemmaAdsNotChangesConll() + + public function testLemmaContentChangesNullInLemmaFieldInJson() { + + $relations = $this->generateRelationsTestData(); + $lemmas = array(); + // args for call without lemma + $LemmaExists = False; + $annotations_by_id = $this->generateAnnotation_By_IdTestData(True,False,$LemmaExists); + $annotations = $this->generateAnnotationsFromAnnotations_By_Id($annotations_by_id); + // invoke tested method + list($conll,$json_builder) = $this->protectedMethod->invoke(new ConllAndJsonFactory(),$this->ccl,$this->tokens,$relations,$annotations,$this->tokens_ids,$annotations_by_id,$lemmas); + + // args for call with lemma + $LemmaExists = True; + $annotations_by_id = $this->generateAnnotation_By_IdTestData(True,False,$LemmaExists); + $annotations = $this->generateAnnotationsFromAnnotations_By_Id($annotations_by_id); + // invoke tested method + list($conll_wL,$json_builder_wL) = $this->protectedMethod->invoke(new ConllAndJsonFactory(),$this->ccl,$this->tokens,$relations,$annotations,$this->tokens_ids,$annotations_by_id,$lemmas); + + // json results after add lemma: + // field 'lemma' changes from null to lemma text + $expectedJsonWithLemma = $json_builder; + $expectedJsonWithLemma['annotations'][0]['lemma'] = $annotations[0]['lemma']; + $this->assertEquals($expectedJsonWithLemma,$json_builder_wL); + + } // testLemmaContentChangesNullInLemmaFieldInJson() + + public function testTokensWithoutAnnotationHasOAnntag() { + + // args for call w/o annotations + $relations = array(); + $lemmas = array(); + $annotations_by_id = array(); + $annotations = $this->generateAnnotationsFromAnnotations_By_Id($annotations_by_id); + // invoke tested method + list($conll,$json_builder) = $this->protectedMethod->invoke(new ConllAndJsonFactory(),$this->ccl,$this->tokens,$relations,$annotations,$this->tokens_ids,$annotations_by_id,$lemmas); + + $expectedAnnTags = "O"; + $fromLine = 3; + $annTags = $this->extractAnntagsFromConllLines($conll,$fromLine); + $this->assertEquals($expectedAnnTags,$annTags); + + } // testTokensWithoutAnnotationHasOAnntag() + + public function testFirstTokenIntoAnnotationHasBAnntag() { + + $annotationTokenLine = 3; + $relations = array(); + $lemmas = array(); + // call args for annotations without "name" field + $fieldsForAnnotationIdExtractorExists = False; + $annotations_by_id = $this->generateAnnotation_By_IdTestData(True,$fieldsForAnnotationIdExtractorExists); + $annotations = $this->generateAnnotationsFromAnnotations_By_Id($annotations_by_id); + // invoke tested method + list($conll,$json_builder) = $this->protectedMethod->invoke(new ConllAndJsonFactory(),$this->ccl,$this->tokens,$relations,$annotations,$this->tokens_ids,$annotations_by_id,$lemmas); + + $expectedAnnTags = "B-".'nam_adj'; // annotation type glued + $annTags = $this->extractAnntagsFromConllLines($conll,$annotationTokenLine); + $this->assertEquals($expectedAnnTags,$annTags); + + // call args for annotations with "name" field + $fieldsForAnnotationIdExtractorExists = True; + $annotations_by_id = $this->generateAnnotation_By_IdTestData(True,$fieldsForAnnotationIdExtractorExists); + $annotations = $this->generateAnnotationsFromAnnotations_By_Id($annotations_by_id); + // invoke tested method + list($conll,$json_builder) = $this->protectedMethod->invoke(new ConllAndJsonFactory(),$this->ccl,$this->tokens,$relations,$annotations,$this->tokens_ids,$annotations_by_id,$lemmas); + + $expectedAnnTags = "B-".'nam_adj'; // annotation type glued + $annTags = $this->extractAnntagsFromConllLines($conll,$annotationTokenLine); + $this->assertEquals($expectedAnnTags,$annTags); + + } // testFirstTokenIntoAnnotationHasBAnntag() + + public function testNextTokensIntoAnnotationHasIAnntag() { + + $relations = array(); + $lemmas = array(); + // call args for annotations without "name" field + $fieldsForAnnotationIdExtractorExists = False; + $annotations_by_id = $this->generateAnnotation_By_IdTestData(True,$fieldsForAnnotationIdExtractorExists); + // expand annotation 1 to charpos 20 includes 2 next tokens + $annotations_by_id[1]['to']=14; + $annotations = $this->generateAnnotationsFromAnnotations_By_Id($annotations_by_id); + // invoke tested method + list($conll,$json_builder) = $this->protectedMethod->invoke(new ConllAndJsonFactory(),$this->ccl,$this->tokens,$relations,$annotations,$this->tokens_ids,$annotations_by_id, $lemmas); + + $expectedAnnTags = "I-".'nam_adj'; // annotation type glued + // for tokens in lines 4 and 5 + $this->assertEquals($expectedAnnTags,$this->extractAnntagsFromConllLines($conll,4)); + $this->assertEquals($expectedAnnTags,$this->extractAnntagsFromConllLines($conll,5)); + + // call args for annotations with "name" field + $fieldsForAnnotationIdExtractorExists = True; + $annotations_by_id = $this->generateAnnotation_By_IdTestData(True,$fieldsForAnnotationIdExtractorExists); + // expand annotation 1 to charpos 20 includes 2 next tokens + $annotations_by_id[1]['to']=14; + $annotations = $this->generateAnnotationsFromAnnotations_By_Id($annotations_by_id); + // invoke tested method + list($conll,$json_builder) = $this->protectedMethod->invoke(new ConllAndJsonFactory(),$this->ccl,$this->tokens,$relations,$annotations,$this->tokens_ids,$annotations_by_id,$lemmas); + + $expectedAnnTags = "I-nam_adj"; + // for tokens in lines 4 and 5 + $this->assertEquals($expectedAnnTags,$this->extractAnntagsFromConllLines($conll,4)); + $this->assertEquals($expectedAnnTags,$this->extractAnntagsFromConllLines($conll,5)); + + } // testNextTokensIntoAnnotationHasIAnntag() + + public function testTokenInto2AnnotationsHasJoinedAnntags() { + + $relations = array(); // no relations + $lemmas = array(); // no lemmas + // call args for two annotations on this same token + $annotations_by_id = $this->generateAnnotation_By_IdTestData(); + // copy 1 anntotation to second one on this same + $annotations_by_id[2] = $annotations_by_id[1]; + $annotations_by_id[2]['id'] = 2; // correct annotation id + $annotations_by_id[2]['type'] = '2nd'; // change ann type name + $annotations = $this->generateAnnotationsFromAnnotations_By_Id($annotations_by_id); + // invoke tested method + list($conll,$json_builder) = $this->protectedMethod->invoke(new ConllAndJsonFactory(),$this->ccl,$this->tokens,$relations,$annotations,$this->tokens_ids,$annotations_by_id,$lemmas); + + // token in line 3 should have two annTags + $expectedAnnTags = "B-nam_adj:B-2nd"; + $this->assertEquals($expectedAnnTags,$this->extractAnntagsFromConllLines($conll,3)); + + } // testTokenInto2AnnotationsHasJoinedAnntags() + +/* class ConllAndJsonFactory has only 1 function + function exportToConllAndJson($file_path_without_ext, $ccl, $tokens, $relations, $annotations, $tokens_ids, $annotations_by_id, $lemmas) +*/ + + public function testDeliveredDataAreWrittenToFiles() { + + $conll = "jakiś text"; + $json_builder = array("a"=>1); + + // this values doesn't matter + $tokens = array(); + $relations = array(); + $annotations = array(); + $tokens_ids = array(); + $annotations_by_id = array(); + $lemmas = array(); + + // self-mocking another method + $mockedMethodNamesList = array('makeConllAndJsonExportData'); + $mockedResult = array($conll,$json_builder); + $mock = $this->getMockBuilder(ConllAndJsonFactory::class) + -> setMethods($mockedMethodNamesList) // ustawia je na null + -> getMock(); + $mock // i mockuje na zwracanie określonego rezultatu + -> method('makeConllAndJsonExportData') + -> will($this->returnValue($mockedResult)); + + // metoda exportToConllAndJson() powinna zachować obsługę oryginalną + $mock->exportToConllAndJson($this->file_path_without_ext,$this->ccl,$tokens,$relations,$annotations,$tokens_ids,$annotations_by_id,$lemmas); + + $expectedConll = $conll; + $conllFileName = $this->file_path_without_ext.".conll"; + $resultConll = file_get_contents($conllFileName); + $this->assertEquals($expectedConll,$resultConll); + $expectedJson = +'{ + "a": 1 +}'; + $jsonFileName = $this->file_path_without_ext.".json"; + $resultJson = file_get_contents($jsonFileName); + $this->assertEquals($expectedJson,$resultJson); + + } // testDeliveredDataAreWrittenToFiles + +// protected function makeLemmaCache(array $lemma) + + public function testMakelemmacacheReturnsEmptyIndexOnEmptyArray() { + + $lemmas = array(); + + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject(ConllAndJsonFactory::class,'makeLemmaCache'); + + $result = $protectedMethod->invokeArgs(new ConllAndJsonFactory(),array($lemmas)); + + $this->assertEquals(array(),$result); + + } // testMakelemmacacheReturnsEmptyIndexOnEmptyArray() + + public function testMakelemmacacheOnFullDataMakesIndexArray() { + + $lemmas = array( + ['report_annotation_id'=>5, 'lemma'=>'lemma5'], // [0] + ['report_annotation_id'=>2, 'lemma'=>'lemma2'], // [1] + [ 'lemma'=>'lemma_no_ann_id'], // no annotation id field + ['report_annotation_id'=>7, ], // [3] no lemma field + ); + + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject(ConllAndJsonFactory::class,'makeLemmaCache'); + + $result = $protectedMethod->invokeArgs(new ConllAndJsonFactory(),array($lemmas)); + + $expectedResult = array( + 2=>['idx'=>1, 'lemma'=>'lemma2'], + 5=>['idx'=>0, 'lemma'=>'lemma5'], + 7=>['idx'=>3, 'lemma'=>null], + ); + $this->assertEquals($expectedResult,$result); + + } // testMakelemmacacheOnFullDataMakesIndexArray() + +} // ConllAndJsonFactoryTest class + +?> diff --git a/phpunit/tests/engine/include/export/CorpusExporterTest.php b/phpunit/tests/engine/include/export/CorpusExporterTest.php index 71c8e0d1..3d453d58 100644 --- a/phpunit/tests/engine/include/export/CorpusExporterTest.php +++ b/phpunit/tests/engine/include/export/CorpusExporterTest.php @@ -1,23 +1,59 @@ virtualDir = vfsStream::setup('root',null,[]); + + } // setUp() + public function test_exportToCcl_createOutput() { + $output_folder = $this->virtualDir->url(); + $selectors_description = array(); + $extractors_description = array(); // array of strings + $lists_description = array(); $table = array( '1' => 'jeden' ); - $dbcorpus = $this->getMockBuilder('DbCorpus')->getMock(); - $dbcorpus->method('getSubcorpora') + $mockCorpusExporter = $this->getMockBuilder(CorpusExporter::class) + -> disableArgumentCloning() + -> setMethods(array( + 'parse_extractor', + 'parse_lists', + 'getSubcorporaList', + 'export_document', + 'writeConsoleMessage' + )) -> getMock(); + // przygotowuje listę wszystkich podkorpusów w postaci id=>nazwa + // i ładuje do zmiennej $subcorpora + $mockCorpusExporter -> expects($this->once()) + -> method('getSubcorporaList') ->will($this->returnValue($table)); - - $ce = new CorpusExporter($dbcorpus); - //$result = $ce->exportToCcl('','','',''); - $this->assertEquals('',$result); + $mockCorpusExporter -> expects($this->never()) + -> method('parse_extractor'); + $mockCorpusExporter -> expects($this->never()) + -> method('parse_lists'); + $mockCorpusExporter -> expects($this->never()) + -> method('export_document'); + // write console msgs + $mockCorpusExporter -> expects($this->at(1)) + -> method('writeConsoleMessage') + -> with("Liczba dokumentów do eksportu: 0\n"); + $mockCorpusExporter -> expects($this->at(2)) + -> method('writeConsoleMessage') + -> with("\n"); + + $mockCorpusExporter->exportToCcl($output_folder,$selectors_description,$extractors_description,$lists_description); } diff --git a/phpunit/tests/engine/include/export/CorpusExporter_part0_Test.php b/phpunit/tests/engine/include/export/CorpusExporter_part0_Test.php index 7b5a4d70..42780d2a 100644 --- a/phpunit/tests/engine/include/export/CorpusExporter_part0_Test.php +++ b/phpunit/tests/engine/include/export/CorpusExporter_part0_Test.php @@ -1,19 +1,19 @@ mock_parse_extractor($emptyData); + $result = $protectedMethod->invokeArgs($ce,array($emptyData)); } catch(Exception $e) { // expected Exception "Niepoprawny opis ekstraktora " $this->assertInstanceOf(\Exception::class,$e); @@ -28,10 +28,11 @@ public function test_parse_extractor_throwsException_on_emptyText(){ public function test_parse_extractor_throwsException_on_ambigousText(){ $syntacticallyImproperData = 'jakieś bzdury'; - $ce = new CorpusExporter_mock(); + $ce = new CorpusExporter(); + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($ce,'parse_extractor'); try { - $result = $ce->mock_parse_extractor($syntacticallyImproperData); + $result = $protectedMethod->invokeArgs($ce,array($syntacticallyImproperData)); } catch(Exception $e) { // expected Exception "Niepoprawny opis ekstraktora " $this->assertInstanceOf(\Exception::class,$e); @@ -46,14 +47,17 @@ public function test_parse_extractor_throwsException_on_ambigousText(){ public function test_parse_extractor_throwsException_on_nonText(){ $nonTextData = array(); - $ce = new CorpusExporter_mock(); + $ce = new CorpusExporter(); + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($ce,'parse_extractor'); + //$result = $protectedMethod->invokeArgs($ce,array($nonTextData)); try { - $result = $ce->mock_parse_extractor($emptyData); + $result = $protectedMethod->invokeArgs($ce,array($nonTextData)); } catch(Exception $e) { // expected Exception "Niepoprawny opis ekstraktora " $this->assertInstanceOf(\Exception::class,$e); - $this->assertEquals("Niepoprawny opis ekstraktora ",$e->getMessage()); + $this->assertEquals("Niepoprawny opis ekstraktora ", + $e->getMessage()); return; } // no exception throwed on empty data @@ -73,8 +77,9 @@ public function test_parse_extractor() // zamieniamy nazwę flagi na duże litery, aby stestować lowercasing $extractorDescriptionwithUC = str_replace('dg','DG',$extractorDescription); - $ce = new CorpusExporter_mock(); - $result = $ce->mock_parse_extractor($extractorDescriptionwithUC); + $ce = new CorpusExporter(); + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($ce,'parse_extractor'); + $result = $protectedMethod->invokeArgs($ce,array($extractorDescriptionwithUC)); /* + 'flag_name' => '1_key_dg' + 'flag_ids' => Array (...) @@ -84,7 +89,7 @@ public function test_parse_extractor() + 'annotation_set_ids' => Array (...) + 'annotation_subset_ids' => null + 'stages' => null - ) ++ 'relation_stages' => array() + 'extractor' => Closure Object (...) */ $this->assertTrue(is_array($result)); @@ -96,7 +101,7 @@ public function test_parse_extractor() $this->assertEquals(array(3),$result[0]["flag_ids"]); $this->assertEquals($extractorDescription,$result[0]["name"]); $this->assertTrue(is_array($result[0]['params'])); - $this->assertEquals(9,count($result[0]['params'])); + $this->assertEquals(10,count($result[0]['params'])); $this->assertTrue(is_array($result[0]['params']['user_ids'])); $this->assertEquals(array(70),$result[0]["params"]['user_ids']); $this->assertTrue(is_array($result[0]['params']['annotation_set_ids'])); @@ -135,7 +140,7 @@ public function test_parse_extractor() "type" =>'chunk_np', "group_id" =>7, "annotation_subset_id" =>22, - "lemma" =>null, + //"lemma" =>null, - this is removed by custom extractor "login" =>'anna.j.koch', "screename" =>'anna.j.koch' ); @@ -146,7 +151,7 @@ public function test_parse_extractor() 'SELECT a.*, at.name as type, at.group_id, at.annotation_subset_id, l.lemma, u.login, u.screename FROM reports_annotations_optimized a LEFT JOIN reports_annotations_lemma l ON (a.id = l.report_annotation_id) JOIN annotation_types at ON (a.type_id = at.annotation_type_id) LEFT JOIN users u ON (u.user_id = a.user_id) WHERE a.report_id = ?', $allOptimizedAnnotationData ); - $params = array(); // empty + $params = array("user_ids"=>null,'annotation_set_ids'=>null,'annotation_subset_ids'=>null,'stages'=>null,'lemma_set_ids'=>null,'lemma_subset_ids'=>null,'attributes_annotation_set_ids'=>null,'attributes_annotation_subset_ids'=>null,'relation_set_ids'=>null); // empty $funcResult = array('annotations'=>array(),"relations"=>array(),"lemmas"=>array(),"attributes"=>array()); // empty answer template $extractorFunc($report_id,$params,$funcResult); $expectedResult = array('annotations'=>$allOptimizedAnnotationData,"relations"=>array(),"lemmas"=>array(),"attributes"=>array()); @@ -160,7 +165,7 @@ public function test_parse_extractor() $this->assertEquals($expectedResult,$funcResult); // with params set - all fields must exists, all must be arrays - $params = array("user_ids"=>array(70),"annotation_set_ids"=>array(12),"annotation_subset_ids"=>array(3),"stages"=>array('final')); + $params = array("user_ids"=>array(70),"annotation_set_ids"=>array(12),"annotation_subset_ids"=>array(3),"stages"=>array('final'),'lemma_set_ids'=>null,'lemma_subset_ids'=>null,'attributes_annotation_set_ids'=>null,'attributes_annotation_subset_ids'=>null,'relation_set_ids'=>null); $dbEmu->setResponse("fetch_rows", "SELECT a.*, at.name as type, at.group_id, at.annotation_subset_id, l.lemma, u.login, u.screename FROM reports_annotations_optimized a LEFT JOIN reports_annotations_lemma l ON (a.id = l.report_annotation_id) JOIN annotation_types at ON (a.type_id = at.annotation_type_id) LEFT JOIN users u ON (u.user_id = a.user_id) WHERE a.report_id = ? AND at.group_id IN (12) AND at.annotation_subset_id IN (3) AND a.user_id IN (70) AND a.stage IN ('final')", $allOptimizedAnnotationData @@ -171,7 +176,7 @@ public function test_parse_extractor() $this->assertEquals($expectedResult,$funcResult); // some of the params field may be empty array - $params = array("user_ids"=>array(70),"annotation_set_ids"=>array(12),"annotation_subset_ids"=>array(),"stages"=>array('final')); + $params = array("user_ids"=>array(70),"annotation_set_ids"=>array(12),"annotation_subset_ids"=>array(),"stages"=>array('final'),'lemma_set_ids'=>null,'lemma_subset_ids'=>null,'attributes_annotation_set_ids'=>null,'attributes_annotation_subset_ids'=>null,'relation_set_ids'=>null); $dbEmu->setResponse("fetch_rows", "SELECT a.*, at.name as type, at.group_id, at.annotation_subset_id, l.lemma, u.login, u.screename FROM reports_annotations_optimized a LEFT JOIN reports_annotations_lemma l ON (a.id = l.report_annotation_id) JOIN annotation_types at ON (a.type_id = at.annotation_type_id) LEFT JOIN users u ON (u.user_id = a.user_id) WHERE a.report_id = ? AND at.group_id IN (12) AND at.annotation_subset_id IN () AND a.user_id IN (70) AND a.stage IN ('final')", $allOptimizedAnnotationData @@ -181,7 +186,7 @@ public function test_parse_extractor() $expectedResult = array('annotations'=>$allOptimizedAnnotationData,"relations"=>array(),"lemmas"=>array(),"attributes"=>array()); $this->assertEquals($expectedResult,$funcResult); // some of the params field may be null - $params = array("user_ids"=>array(70),"annotation_set_ids"=>array(12),"annotation_subset_ids"=>null,"stages"=>array('final')); + $params = array("user_ids"=>array(70),"annotation_set_ids"=>array(12),"annotation_subset_ids"=>null,"stages"=>array('final'),'lemma_set_ids'=>null,'lemma_subset_ids'=>null,'attributes_annotation_set_ids'=>null,'attributes_annotation_subset_ids'=>null,'relation_set_ids'=>null); $dbEmu->setResponse("fetch_rows", "SELECT a.*, at.name as type, at.group_id, at.annotation_subset_id, l.lemma, u.login, u.screename FROM reports_annotations_optimized a LEFT JOIN reports_annotations_lemma l ON (a.id = l.report_annotation_id) JOIN annotation_types at ON (a.type_id = at.annotation_type_id) LEFT JOIN users u ON (u.user_id = a.user_id) WHERE a.report_id = ? AND at.group_id IN (12) AND a.user_id IN (70) AND a.stage IN ('final')", $allOptimizedAnnotationData @@ -205,13 +210,12 @@ public function test_parse_extractor() $ReturnedDataRow = array( "id"=>1, "report_id"=>$report_id, "type_id"=>$type, "type"=>'typ annotacji', "group"=>1, "from"=>$from, "to"=>$to, "text"=>$text, "user_id"=>$user_id, "creation_time"=>'2022-12-21 18:16:58', "stage"=>'final', "source"=>'auto', "prop"=>$value); $allReturnedDataRows = array( $ReturnedDataRow ); $dbEmu->setResponse("fetch_rows", -"SELECT *, raa.`value` AS `prop` FROM reports_annotations ra LEFT JOIN annotation_types at ON (ra.type=at.name) LEFT JOIN reports_annotations_attributes raa ON (ra.id=raa.annotation_id) WHERE ( ra.stage = 'final' AND report_id IN ($report_id)) GROUP BY ra.id ORDER BY `from`", +"SELECT ra.*, at.*, raa.annotation_id, raa.annotation_attribute_id, raa.`user_id` AS `attr_user_id`, raa.`value` AS `prop` FROM reports_annotations ra LEFT JOIN annotation_types at ON (ra.type=at.name) LEFT JOIN reports_annotations_attributes raa ON (ra.id=raa.annotation_id) WHERE ( ra.stage = 'final' AND report_id IN ($report_id)) GROUP BY ra.id ORDER BY `from`", $allReturnedDataRows ); - - - $ce = new CorpusExporter_mock(); - $result = $ce->mock_parse_extractor($extractorDescription); + $ce = new CorpusExporter(); + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($ce,'parse_extractor'); + $result = $protectedMethod->invokeArgs($ce,array($extractorDescription)); /* var_dump($result); [0]=> array(5) { diff --git a/phpunit/tests/engine/include/export/CorpusExporter_part10_Test.php b/phpunit/tests/engine/include/export/CorpusExporter_part10_Test.php new file mode 100644 index 00000000..809a9ca9 --- /dev/null +++ b/phpunit/tests/engine/include/export/CorpusExporter_part10_Test.php @@ -0,0 +1,680 @@ +virtualDir = vfsStream::setup('root',null,[]); + + } // setUp() + +// protected function export_document($report_id, $extractors, $disamb_only, &$extractor_stats, &$lists, $output_folder, $subcorpora, $tagging_method){ + + public function testExport_documentCallsAllProcessingMethods() { + // export_document() dumb parameters + $report_id = 1; + $fakeExtractor = array(); + $extractors = array( $fakeExtractor ); + $disamb_only = true; + $extractor_stats = array(); + $lists = array(); + $output_folder = $this->virtualDir->url(); + $subcorpora = ''; + $tagging_method = 'tagger'; + + // results returned by mocking methods + $reportContent = "tekst dokumentu raportu"; + $reportFlags = array('flagnamelowercase'=>array(-1)); + $reportTokens = array(); + $reportTags = array(); + $report = array( 'id'=>$report_id, 'content'=>$reportContent ); + + $mockCorpusExporter = $this->getMockBuilder(CorpusExporter::class) + -> disableArgumentCloning() + -> setMethods(array('getFlagsByReportId','getTokenByReportId', + 'getReportTagsByTokens','getReportById', + 'getReportExtById','exportReportContent', + 'updateLists','createIniFile', + 'checkIfAnnotationForLemmaExists', + 'checkIfAnnotationForRelationExists', + 'sortUniqueAnnotationsById', + 'dispatchElements','generateCcl', + 'runExtractor')) + -> getMock(); + $mockCorpusExporter -> method('getFlagsByReportId') + -> will($this->returnValue($reportFlags)); + $mockCorpusExporter -> method('getTokenByReportId') + -> will($this->returnValue($reportTokens)); + $mockCorpusExporter -> method('getReportTagsByTokens') + -> will($this->returnValue($reportTags)); + $mockCorpusExporter -> method('getReportById') + -> will($this->returnValue($report)); + + // tested methods called exactly once with proper args: + $expectedFlags = $reportFlags; + $expectedExtractor = $fakeExtractor; + $expectedElements = array( + 'annotations' => array(), + 'relations' => array(), + 'lemmas' => array(), + 'attributes' => array() + ); + $expectedExtractorStats = $extractor_stats; + $mockCorpusExporter -> expects($this->once()) + ->method('runExtractor') + ->with($expectedFlags,$report_id,$expectedExtractor,$expectedElements,$expectedExtractorStats); + $expectedReport = $report; + $expectedTokens = $reportTokens; + $expectedTagsByTokens = array(); + $fileName = str_pad($report_id,8,'0',STR_PAD_LEFT); + $returnedCcl = new CclExportDocument($expectedReport,$expectedTokens,$expectedTagsByTokens); + $returnedCcl -> setFileName($fileName); + $mockCorpusExporter -> expects($this->once()) + ->method('generateCcl') + ->with($expectedReport,$expectedTokens,$expectedTagsByTokens) + -> will($this->returnValue($returnedCcl)); + $expectedElements = array("annotations"=>array(), "relations"=>array(), "lemmas"=>array(), "attributes"=>array()); + $returnedTableList = [array(),array(),array(),array()]; + $mockCorpusExporter -> expects($this->once()) + ->method('dispatchElements') + ->with($expectedElements) + -> will($this->returnValue($returnedTableList)); + $expectedAnnotations = array(); + $returnedAnnotationsById = array(); + $mockCorpusExporter -> expects($this->once()) + ->method('sortUniqueAnnotationsById') + ->with($report_id,$expectedAnnotations) + -> will($this->returnValue($returnedAnnotationsById)); + $expectedRelations = array(); + $mockCorpusExporter -> expects($this->once()) + ->method('checkIfAnnotationForRelationExists') + ->with($report_id,$expectedRelations,$returnedAnnotationsById); + $expectedLemmas = array(); + $mockCorpusExporter -> expects($this->once()) + ->method('checkIfAnnotationForLemmaExists') + ->with($report_id,$expectedLemmas,$returnedAnnotationsById); + $expectedReportArg = $report; + $expectedBaseFileName = $output_folder.'/'.str_pad($report_id,8,'0',STR_PAD_LEFT); + $mockCorpusExporter -> expects($this->once()) + ->method('createIniFile') + ->with($expectedReportArg,$subcorpora,$expectedBaseFileName); + $expectedFlags = $reportFlags; + $expectedFileNameWithoutExt = str_pad($report_id,8,'0',STR_PAD_LEFT); + $mockCorpusExporter -> expects($this->once()) + ->method('updateLists') + ->with($expectedFlags,$expectedFileNameWithoutExt,$lists); + $expectedReportArg = $report; + $mockCorpusExporter -> expects($this->once()) + ->method('exportReportContent') + ->with($expectedReportArg,$expectedBaseFileName); + + + // reflection for acces to private elements + $protectedMethod = new ReflectionMethod($mockCorpusExporter,'export_document'); + $protectedMethod->setAccessible(True); + + // tested call + $protectedMethod->invokeArgs($mockCorpusExporter,array($report_id,$extractors,$disamb_only,&$extractor_stats,&$lists,$output_folder,$subcorpora,$tagging_method)); + + } // testExport_documentCallsAllProcessingMethods + +// protected function exportReportContent($report,$file_path_without_ext){...} + + public function testExportreportcontentsExportsDocumentContentToTxtFile() { + + $report_id = 1; + $reportContent = "tekst dokumentu raportu"; + $file_path_without_ext = $this->virtualDir->url().'/testname'; + $report = array( 'id'=>$report_id, 'content'=>$reportContent ); + + // reflection for acces to private elements + $protectedMethod = new ReflectionMethod('CorpusExporter','exportReportContent'); + $protectedMethod->setAccessible(True); + $ce = new CorpusExporter(); + $export_errorsPrivateProperty = new ReflectionProperty($ce,'export_errors'); + $export_errorsPrivateProperty->setAccessible(True); + + $result=$protectedMethod->invokeArgs($ce,array($report,$file_path_without_ext)); + + // returns True + $this->assertTrue($result); + // no errors collected + $expectedErrors = array(); + $this->assertEquals($expectedErrors, + $export_errorsPrivateProperty->getValue($ce) + ); + //check TxtFile + $expectedTxtContent = $reportContent; + $resultTxtFile = file_get_contents($file_path_without_ext.'.txt'); + $this->assertEquals($expectedTxtContent,$resultTxtFile); + + } // testExportreportcontentsExportsDocumentContentToTxtFile() + + public function testExportreportcontentsWithOversizedDocumentSetInternalError() { + $report_id = 1; + $reportContent = str_repeat('s',300000); // content too long + $file_path_without_ext = $this->virtualDir->url().'/testname'; + $report = array( 'id'=>$report_id, 'content'=>$reportContent ); + + // reflection for acces to private elements + $protectedMethod = new ReflectionMethod('CorpusExporter','exportReportContent'); + $protectedMethod->setAccessible(True); + $ce = new CorpusExporter(); + $export_errorsPrivateProperty = new ReflectionProperty($ce,'export_errors'); + $export_errorsPrivateProperty->setAccessible(True); + + $result=$protectedMethod->invokeArgs($ce,array($report,$file_path_without_ext)); + + // returns False + $this->assertFalse($result); + // internal errors table + $internalErrorsTable = $export_errorsPrivateProperty->getValue($ce); + $expectedErrorsCount = 1; + $this->assertEquals($expectedErrorsCount,count($internalErrorsTable)); + $expectedErrorsKey = "Text too long to display (over 50k characters)"; + $this->assertEquals(1,$internalErrorsTable[8]['details']['errors'][$expectedErrorsKey]); + + } // testExportreportcontentsWithOversizedDocumentSetInternalError() + +// protected function updateLists($flags,$reportFileName,&$lists) {...} + + public function testUpdatelistsEmptyCallDoNothing() { + + $flags = array(); + $file_name_without_ext = 'reportFileName'; + $lists = array(); + + // reflection for acces to private elements + $protectedMethod = new ReflectionMethod('CorpusExporter','updateLists'); + $protectedMethod->setAccessible(True); + + $ce = new CorpusExporter(); + $protectedMethod->invokeArgs($ce,array($flags,$file_name_without_ext,&$lists)); + + // check results + $expectedLists = array(); + $this->assertEquals($expectedLists,$lists); + + } // testUpdatelistsEmptyCallDoNothing() + + public function testUpdatelistsOnEmptyListsDoNothing() { + + $testFlagName = 'TFN'; + $testFlagId = 123; + $listName = 'ix'; + + $flags = array( + $testFlagName => $testFlagId + ); + $file_name_without_ext = 'reportFileName'; + $lists = array(); + + // reflection for acces to private elements + $protectedMethod = new ReflectionMethod('CorpusExporter','updateLists'); + $protectedMethod->setAccessible(True); + + $ce = new CorpusExporter(); + $listsBeforeCall = $lists; + $protectedMethod->invokeArgs($ce,array($flags,$file_name_without_ext,&$lists)); + + // check results + $expectedLists = $listsBeforeCall; + $this->assertEquals($expectedLists,$lists); + + } // testUpdatelistsOnEmptyListsDoNothing() + + public function testUpdatelistsSetsDocument_namesToLists() { + + $testFlagName = 'TFN'; + $testFlagId = 123; + $listName = 'ix'; + + $flags = array( + $testFlagName => $testFlagId + ); + $file_name_without_ext = 'reportFileName'; + $lists = array( + $listName => array( + "flags" => array( + array( "flag_name"=>'flagName', + "flag_ids"=> array(1,2)), + array( "flag_name"=>$testFlagName, "flag_ids"=> array(1,$testFlagId)), + ) + ) + ); + + // reflection for acces to private elements + $protectedMethod = new ReflectionMethod('CorpusExporter','updateLists'); + $protectedMethod->setAccessible(True); + + $ce = new CorpusExporter(); + $listsBeforeCall = $lists; + $protectedMethod->invokeArgs($ce,array($flags,$file_name_without_ext,&$lists)); + + // check results + $expectedLists = $listsBeforeCall; + $expectedLists[$listName]["document_names"][$file_name_without_ext.".xml"] = 1; + $this->assertEquals($expectedLists,$lists); + + } // testUpdatelistsSetsDocument_namesToLists() + +// protected function createIniFile($report,$file_path_without_ext) {...} + + public function testCreateinifileExportsReportMetadataToIniFile() { + + $report_id = 1; + $reportContent = "tekst dokumentu raportu"; + $reportDate = '23/12/2023'; + $reportTitle = 'TYTUŁ RAPORTU'; + $reportSource = 'ŹRÓDŁO RAPORTU'; + $reportAuthor = 'AUTOR RAPORTU'; + $reportTokenization = 'TOKENIZACJA'; + $reportNonidExtKey = 'nonid'; + $reportNonidExtValue = 13; + $reportNonLNKey = ' klucz ze spacjami'; + $reportNonLNKey_converted = '_klucz_ze_spacjami'; + $reportNonLNValue = 48; + $subcorpusKey = 341; + $subcorpusName = 'SUBCORPUS NAME'; + $subcorpora = array( $subcorpusKey => $subcorpusName ); + $file_path_without_ext = $this->virtualDir->url().'/testname'; + $report = array( 'id'=>$report_id, 'subcorpus_id'=>$subcorpusKey, + 'date' => $reportDate, 'title' => $reportTitle, + 'source' => $reportSource, 'author' => $reportAuthor, + 'tokenization' => $reportTokenization ); + $reportExt = array( 'id' => 12, // id is excluded from .ini + $reportNonLNKey => $reportNonLNValue, + $reportNonidExtKey => $reportNonidExtValue ); + + $mockCorpusExporter = $this->getMockBuilder(CorpusExporter::class) + -> disableArgumentCloning() + -> setMethods(array('getReportExtById')) + -> getMock(); + $mockCorpusExporter -> method('getReportExtById') -> will($this->returnValue($reportExt)); + + // reflection for acces to private elements + $protectedMethod = new ReflectionMethod('CorpusExporter','createIniFile'); + $protectedMethod->setAccessible(True); + + $result=$protectedMethod->invokeArgs($mockCorpusExporter,array($report,$subcorpora,$file_path_without_ext)); + + //check Ini File + $expectedIniContent = +"[document] +id = 1 +date = $reportDate +title = $reportTitle +source = $reportSource +author = $reportAuthor +tokenization = $reportTokenization +subcorpus = $subcorpusName + +[metadata] +$reportNonLNKey_converted = $reportNonLNValue +$reportNonidExtKey = $reportNonidExtValue"; + $resultIniFile = file_get_contents($file_path_without_ext.'.ini'); + $this->assertEquals($expectedIniContent,$resultIniFile); + + } // testCreateinifileExportsReportMetadataToIniFile() + +// protected function checkIfAnnotationForLemmaExists($lemmas,$annotations_by_id) {...} + + public function testCheckifannotationforlemmaexistsReturnsTrueIfAllLemmasMatched() { + $report_id = 1; // needed only for error reporting text + $annoId1 = 10; $annoId2 = 20; + $lemmas = array( + array( "id"=>$annoId1 ), + array( "id"=>$annoId2 ) + ); + $annotationsById = array( $annoId1 => True, $annoId2 => True ); + + // reflection for acces to private elements + $protectedMethod = new ReflectionMethod('CorpusExporter','checkIfAnnotationForLemmaExists'); + $protectedMethod->setAccessible(True); + $ce = new CorpusExporter(); + $export_errorsPrivateProperty = new ReflectionProperty($ce,'export_errors'); + $export_errorsPrivateProperty->setAccessible(True); + + $result=$protectedMethod->invokeArgs($ce,array($report_id,$lemmas,$annotationsById)); + // returns True + $this->assertTrue($result); + + // internal errors table is empty + $internalErrorsTable = $export_errorsPrivateProperty->getValue($ce); + $this->assertEquals(0,count($internalErrorsTable)); + + } // testCheckifannotationforlemmaexistsReturnsTrueIfAllLemmasMatched() + + public function testCheckifannotationforlemmaexistsSetInternalError() { + + $report_id = 1; // needed only for error reporting text + $annoId1 = 10; $annoId2 = 20; + $lemmas = array( + array( "id"=>$annoId1, "lemma"=>'lemma annotacji 1', "group_id"=>1, "name"=>'NAME', "from"=>0, "to"=>4, "type"=>'TYPE' ), + array( "id"=>$annoId2, "lemma"=>'lemma annotacji 2', "group_id"=>1, "name"=>'NAME', "from"=>5, "to"=>13, "type"=>'TYPE' ) + ); + $annotationsById = array( $annoId1 => True ); + + // reflection for acces to private elements + $protectedMethod = new ReflectionMethod('CorpusExporter','checkIfAnnotationForLemmaExists'); + $protectedMethod->setAccessible(True); + $ce = new CorpusExporter(); + $export_errorsPrivateProperty = new ReflectionProperty($ce,'export_errors'); + $export_errorsPrivateProperty->setAccessible(True); + + $result=$protectedMethod->invokeArgs($ce,array($report_id,$lemmas,$annotationsById)); + + // returns False + $this->assertFalse($result); + + // internal errors table + $internalErrorsTable = $export_errorsPrivateProperty->getValue($ce); + $expectedErrorsCount = 1; + $this->assertEquals($expectedErrorsCount,count($internalErrorsTable)); + $expectedErrorsKey = "Brak warstwy anotacji dla lematu."; + $this->assertEquals($expectedErrorsKey,$internalErrorsTable[6]['message']); + + } // testCheckifannotationforlemmaexistsSetInternalError() + +// protected function checkIfAnnotationForRelationExists($relations,$annotations_by_id) { + + public function testCheckifannotationforrelationsexistsReturnsTrueIfAllRelationsMatched() { + $report_id = 1; // needed only for error reporting text + $sourceId1 = 10; $targetId1 = 13; + $sourceId2 = 20; $targetId2 = 27; + $relations = array( + array( "source_id"=>$sourceId1, "target_id"=>$targetId1 ), + array( "source_id"=>$sourceId2, "target_id"=>$targetId2 ) + ); + $annotationsById = array( $sourceId1 => True, $targetId1 => True, + $sourceId2 => True, $targetId2 => True ); + + // reflection for acces to private elements + $protectedMethod = new ReflectionMethod('CorpusExporter','checkIfAnnotationForRelationExists'); + $protectedMethod->setAccessible(True); + $ce = new CorpusExporter(); + $export_errorsPrivateProperty = new ReflectionProperty($ce,'export_errors'); + $export_errorsPrivateProperty->setAccessible(True); + + $result=$protectedMethod->invokeArgs($ce,array($report_id,$relations,$annotationsById)); + // returns True + $this->assertTrue($result); + + // internal errors table is empty + $internalErrorsTable = $export_errorsPrivateProperty->getValue($ce); + $this->assertEquals(0,count($internalErrorsTable)); + + } // testCheckifannotationforrelationsexistsReturnsTrueIfAllRelationsMatched() + + public function testCheckifannotationforrelationsexistsSetInternalError() { + $report_id = 1; // needed only for error reporting text + $sourceId1 = 10; $targetId1 = 13; + $sourceId2 = 20; $targetId2 = 27; + $relations = array( + array( "source_id"=>$sourceId1, "target_id"=>$targetId1, "name"=>'NAME' ), + array( "source_id"=>$sourceId2, "target_id"=>$targetId2, "name"=>'NAME' ) + ); + $annotationsById = array( $targetId1 => True, + $sourceId2 => True ); + + // reflection for acces to private elements + $protectedMethod = new ReflectionMethod('CorpusExporter','checkIfAnnotationForRelationExists'); + $protectedMethod->setAccessible(True); + $ce = new CorpusExporter(); + $export_errorsPrivateProperty = new ReflectionProperty($ce,'export_errors'); + $export_errorsPrivateProperty->setAccessible(True); + + $result=$protectedMethod->invokeArgs($ce,array($report_id,$relations,$annotationsById)); + // returns False + $this->assertFalse($result); + + // internal errors table + $internalErrorsTable = $export_errorsPrivateProperty->getValue($ce); + $expectedErrorsCount = 2; + $this->assertEquals($expectedErrorsCount,count($internalErrorsTable)); + $expectedErrorsKey = "Brak anotacji źródłowej dla relacji."; + $this->assertEquals($expectedErrorsKey,$internalErrorsTable[4]['message']); + $expectedErrorsKey = "Brak anotacji docelowej dla relacji."; + $this->assertEquals($expectedErrorsKey,$internalErrorsTable[5]['message']); + + } // testCheckifannotationforrelationsexistsSetInternalError() + +// protected function sortUniqueAnnotationsById($annotations) {...} + + public function testSortuniqueannotationsbyidReturnsIndexedArray() { + $report_id = 1; // needed only for error reporting text + $anno1 = array( "id"=>1 ); $anno2 = array( "id"=>2 ); + $annotations = array( $anno1,$anno2,$anno2 ); + + // reflection for acces to private elements + $protectedMethod = new ReflectionMethod('CorpusExporter','sortUniqueAnnotationsById'); + $protectedMethod->setAccessible(True); + $ce = new CorpusExporter(); + $export_errorsPrivateProperty = new ReflectionProperty($ce,'export_errors'); + $export_errorsPrivateProperty->setAccessible(True); + + $result=$protectedMethod->invokeArgs($ce,array($report_id,$annotations)); + + $expectedAnnotationById = array( + 1 => $anno1, + 2 => $anno2 + ); + $this->assertEquals($expectedAnnotationById,$result); + + } // testSortuniqueannotationsbyidReturnsIndexedArray() + + public function testSortuniqueannotationsbyidSetInternalError() { + + $report_id = 1; // needed only for error reporting text + $annoWoId = array( "name"=>1 ); $anno2 = array( "id"=>2 ); + $annotations = array( $annoWoId,$anno2,$anno2 ); + + // reflection for acces to private elements + $protectedMethod = new ReflectionMethod('CorpusExporter','sortUniqueAnnotationsById'); + $protectedMethod->setAccessible(True); + $ce = new CorpusExporter(); + $export_errorsPrivateProperty = new ReflectionProperty($ce,'export_errors'); + $export_errorsPrivateProperty->setAccessible(True); + + $result=$protectedMethod->invokeArgs($ce,array($report_id,$annotations)); + + $expectedAnnotationById = array( + 2 => $anno2 + ); + $this->assertEquals($expectedAnnotationById,$result); + + // internal errors table + $internalErrorsTable = $export_errorsPrivateProperty->getValue($ce); + $expectedErrorsCount = 1; + $this->assertEquals($expectedErrorsCount,count($internalErrorsTable)); + $expectedErrorsKey = "Brak identyfikatora anotacji."; + $this->assertEquals($expectedErrorsKey,$internalErrorsTable[3]['message']); + + } // testSortuniqueannotationsbyidSetInternalError() + +// protected function dispatchElements($elements) + + public function testDispatchelementsGeneratesTableList() { + + $annotations = array( 'tableName' => 'annotations' ); + $relations = array( 'tableName' => 'relations' ); + $lemmas = array( 'tableName' => 'lemmas' ); + $attributes = array( 'tableName' => 'attributes' ); + $elements = array( + "annotations" => $annotations, + "relations" => $relations, + "lemmas" => $lemmas, + "attributes" => $attributes + ); + + // reflection for access to private elements + $protectedMethod = new ReflectionMethod('CorpusExporter','dispatchElements'); + $protectedMethod->setAccessible(True); + $ce = new CorpusExporter(); + $export_errorsPrivateProperty = new ReflectionProperty($ce,'export_errors'); + $export_errorsPrivateProperty->setAccessible(True); + + $result=$protectedMethod->invokeArgs($ce,array($elements)); + + $expectedTableList = [$annotations,$relations,$lemmas,$attributes]; + $this->assertEquals($expectedTableList,$result); + + } // testDispatchelementsGeneratesTableList() + +// protected function generateCcl($report,$tokens,$tags_by_tokens) + + public function testGeneratecclReturnsObjectofCclDocumentClass() { + + $report_id = 12; + $report = array( 'id'=>$report_id, 'content'=>'' ); + $tokens = array(); + $tags_by_tokens = array(); + + $ce = new CorpusExporter(); + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($ce,'generateCcl'); + $result=$protectedMethod->invokeArgs($ce,array($report,$tokens,$tags_by_tokens)); + + // result is object of CclDocument class + $this->assertInstanceOf('CclDocument',$result); + // Ccl->fileName is set to name coresponding to report_id + $expectedFileName = str_pad($report_id,8,'0',STR_PAD_LEFT); + $this->assertEquals($expectedFileName,$result->getFilename()); + + } // testGeneratecclReturnsObjectofCclDocumentClass() + + public function testGeneratecclOnExceptionReturnsFalse() { + + $report_id = 13; + $report = array( 'id'=>null ); + $tokens = array(); + $tags_by_tokens = array(); + + // mocking for throw exception emulate + $mockCorpusExporter = $this->getMockBuilder(CorpusExporter::class) + -> disableArgumentCloning() + -> setMethods(array('callCclCreator')) + -> getMock(); + $mockCorpusExporter -> method('callCclCreator') + -> will($this->throwException(new Exception())); + + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($mockCorpusExporter,'generateCcl'); + $export_errorsPrivateProperty = new ReflectionProperty($mockCorpusExporter,'export_errors'); + $export_errorsPrivateProperty->setAccessible(True); + + $result=$protectedMethod->invokeArgs($mockCorpusExporter,array($report,$tokens,$tags_by_tokens)); + + // result should be false + $this->assertFalse($result); + // internal errors table + $internalErrorsTable = $export_errorsPrivateProperty->getValue($mockCorpusExporter); + $expectedErrorsCount = 1; + $this->assertEquals($expectedErrorsCount,count($internalErrorsTable)); + $expectedErrorsKey = "Problem z utworzeniem CCL"; + $this->assertEquals($expectedErrorsKey,$internalErrorsTable[2]['message']); + + } // testGeneratecclOnBadDataReturnsFalse() + +// protected function updateExtractorStats($extractorName,$extractor_stats,$extractor_elements) + + public function testUpdateextractorstatsUpdatesStatsTable() { + + $extractorName = 'nazwa_extraktora'; + $existentType = 'typ istniejący'; + $existentCount = 219; + $newType = 'niestniejacy typ'; + $arrWith2Items = array( 3,4 ); + $extractor_stats = array( + $extractorName => array( + $existentType => $existentCount + ) + ); + $extractor_elements = array( + $newType => $arrWith2Items, + $existentType => $arrWith2Items + ); + + $ce = new CorpusExporter(); + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($ce,'updateExtractorStats'); + $result=$protectedMethod->invokeArgs($ce,array($extractorName,$extractor_stats,$extractor_elements)); + + $expectedStats = array( + $extractorName => array( + $existentType => $existentCount + 2, + $newType => 2 // count of $arrWith2Items + ) + ); + $this->assertEquals($expectedStats,$result); + + } // testUpdateextractorstatsUpdatesStatsTable() + +// protected function runExtractor($flags,$report_id,$extractor,&$elements,&$extractor_stats) + + public function testRunextractorsReturnsChangedElementsAndStats() { + + $report_id = 13; + $annotation1 = array( "id"=>17, "other_field"=>"sth" ); + $flagId = -1; + $flagName = 'xxx'; $flagIds = [$flagId,0,1]; + $flags = array( $flagName=>$flagId ); + $extractorName = "exName"; + $extractorFunc = function ($report_id, $params, &$elements) { + $elements["annotations"]=array( + array( "id"=>17, "other_field"=>"sth" ) // $annotation1 + ); + }; + $extractor = array( + "name" => $extractorName, + "flag_name" => $flagName, + "flag_ids" => $flagIds, + "extractor" => $extractorFunc, + "params" => array() + ); + $elements = array( + "annotations" => array(), + "relations" => array(), + "lemmas" => array(), + "attributes" => array(), + ); + $extractor_stats = array(); + + // mocking for throw exception emulate + $mockCorpusExporter = $this->getMockBuilder(CorpusExporter::class) + -> disableArgumentCloning() + -> setMethods(array('updateExtractorStats')) + -> getMock(); + $expectedName = $extractorName; + $expectedStats = array(); + $expectedElements = array( + "annotations" => array($annotation1), + "relations" => array(), + "lemmas" => array(), + "attributes" => array(), + ); + $returnedStats = array( + $extractorName => array("annotations"=>1,"relations"=>0,"lemmas"=>0,"attributes"=>0) + ); + + $mockCorpusExporter -> expects($this->once()) + -> method('updateExtractorStats') + -> with($expectedName,$expectedStats,$expectedElements) + -> will($this->returnValue($returnedStats)); + + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($mockCorpusExporter,'runExtractor'); + + $protectedMethod->invokeArgs($mockCorpusExporter,array($flags,$report_id,$extractor,&$elements,&$extractor_stats)); + + $expectedAnnotationsElements = array($annotation1); + $this->assertEquals($expectedAnnotationsElements,$elements["annotations"]); + $expectedStats = $returnedStats; + $this->assertEquals($expectedStats,$extractor_stats); + + } // testRunextractorsReturnsChangedElementsAndStats() + +} // CorpusExporter_part10_Test class + +?> diff --git a/phpunit/tests/engine/include/export/CorpusExporter_part11_Test.php b/phpunit/tests/engine/include/export/CorpusExporter_part11_Test.php new file mode 100644 index 00000000..6a0f221a --- /dev/null +++ b/phpunit/tests/engine/include/export/CorpusExporter_part11_Test.php @@ -0,0 +1,230 @@ +1, "orth"=>"nam_adj", "lemma"=>NULL ); + // annotacja z niepustym lematem + $annotation2 = array( "id"=>2, "orth"=>"nam_orth", "lemma"=>"lemat1" ); + $flagId = -1; + $flagName = 'xxx'; $flagIds = [$flagId,0,1]; + $flags = array( $flagName=>$flagId ); + $extractorName = "exName"; + $extractorFunc = function ($report_id, $params, &$elements) { + $elements["annotations"]=array( + // annotation 1 + array( "id"=>1, "orth"=>"nam_adj", "lemma"=>NULL ), + // annotation 2 + array( "id"=>2, "orth"=>"nam_orth", "lemma"=>"lemat1" ) + ); + }; + $extractor = array( + "name" => $extractorName, + "flag_name" => $flagName, + "flag_ids" => $flagIds, + "extractor" => $extractorFunc, + "params" => array() + ); + $elements = array( + "annotations" => array(), + "relations" => array(), + "lemmas" => array(), + "attributes" => array(), + ); + $extractor_stats = array(); + + // mocking for throw exception emulate + $mockCorpusExporter = $this->getMockBuilder(CorpusExporter::class) + -> disableArgumentCloning() + -> setMethods(array('updateExtractorStats')) + -> getMock(); + $expectedName = $extractorName; + $expectedStats = array(); + $expectedElements = array( + "annotations" => array($annotation1,$annotation2), + "relations" => array(), + "lemmas" => array(), + "attributes" => array(), + ); + $returnedStats = array( + $extractorName => array("annotations"=>2,"relations"=>0,"lemmas"=>0,"attributes"=>0) + ); + + $mockCorpusExporter -> expects($this->once()) + -> method('updateExtractorStats') + -> with($expectedName,$expectedStats,$expectedElements) + -> will($this->returnValue($returnedStats)); + + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($mockCorpusExporter,'runExtractor'); + $protectedMethod->invokeArgs($mockCorpusExporter,array($flags,$report_id,$extractor,&$elements,&$extractor_stats)); + + $expectedElements = array( + "annotations" => array( $annotation1, $annotation2 ), + "relations"=>[], "lemmas"=>[], "attributes"=>[] + ); + $this->assertEquals($expectedElements,$elements); + $expectedStats = $returnedStats; + $this->assertEquals($expectedStats,$extractor_stats); + + } // testRunextractorsForExtractorCustomAnnotationsSetsLemmaFieldsInElementsAnnotationsSection() + + // 2b + public function testRunextractorsForExtractorCustomLemmasSetsLemmaFieldsInElementsAnnotationsAndLemmasSection() { + + $report_id = 13; + // annotacja z pustym lematem, z wykonania LEFT JOIN + $annotation1 = array( "id"=>1, "orth"=>"nam_adj", "lemma"=>NULL ); + // annotacja z niepustym lematem + $annotation2 = array( "id"=>2, "orth"=>"nam_orth", "lemma"=>"lemat1" ); + $lemma2 = array( "report_annotation_id" => "2", "lemma" => "lemat1", "id"=>2 ); + $flagId = -1; + $flagName = 'xxx'; $flagIds = [$flagId,0,1]; + $flags = array( $flagName=>$flagId ); + $extractorName = "exName"; + $extractorFunc = function ($report_id, $params, &$elements) { + $elements["annotations"]=array( + // annotation 1 + array( "id"=>1, "orth"=>"nam_adj", "lemma"=>NULL ), + // annotation 2 + array( "id"=>2, "orth"=>"nam_orth", "lemma"=>"lemat1" ) + ); + $elements["lemmas"]=array( + // lemma2 + array( "report_annotation_id" => "2", "lemma" => "lemat1", "id"=>2 ) + ); + }; + $extractor = array( + "name" => $extractorName, + "flag_name" => $flagName, + "flag_ids" => $flagIds, + "extractor" => $extractorFunc, + "params" => array() + ); + $elements = array( + "annotations" => array(), + "relations" => array(), + "lemmas" => array(), + "attributes" => array(), + ); + $extractor_stats = array(); + + // mocking for throw exception emulate + $mockCorpusExporter = $this->getMockBuilder(CorpusExporter::class) + -> disableArgumentCloning() + -> setMethods(array('updateExtractorStats')) + -> getMock(); + $expectedName = $extractorName; + $expectedStats = array(); + $expectedElements = array( + "annotations" => array($annotation1,$annotation2), + "relations" => array(), + "lemmas" => array($lemma2), + "attributes" => array(), + ); + $returnedStats = array( + $extractorName => array("annotations"=>2,"relations"=>0,"lemmas"=>1,"attributes"=>0) + ); + + $mockCorpusExporter -> expects($this->once()) + -> method('updateExtractorStats') + -> with($expectedName,$expectedStats,$expectedElements) + -> will($this->returnValue($returnedStats)); + + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($mockCorpusExporter,'runExtractor'); + $protectedMethod->invokeArgs($mockCorpusExporter,array($flags,$report_id,$extractor,&$elements,&$extractor_stats)); + + $expectedElements = array( + "annotations" => array( $annotation1, $annotation2 ), + "relations"=>[], + "lemmas"=>array($lemma2), + "attributes"=>[] + ); + $this->assertEquals($expectedElements,$elements); + $expectedStats = $returnedStats; + $this->assertEquals($expectedStats,$extractor_stats); + + } // testRunextractorsForExtractorCustomLemmasSetsLemmaFieldsInElementsAnnotationsAndLemmasSection() + + // 3 + public function testRunextractorsForExtractorStandardLemmasSetsLemmaFieldsInElementsLemmasSection() { + + $report_id = 13; + $lemma2 = array( "report_annotation_id" => "2", "lemma" => "lemat1", "id"=>2 ); + $flagId = -1; + $flagName = 'xxx'; $flagIds = [$flagId,0,1]; + $flags = array( $flagName=>$flagId ); + $extractorName = "exName"; + $extractorFunc = function ($report_id, $params, &$elements) { + $elements["lemmas"]=array( + // lemma2 + array( "report_annotation_id" => "2", "lemma" => "lemat1", "id"=>2 ) + ); + }; + $extractor = array( + "name" => $extractorName, + "flag_name" => $flagName, + "flag_ids" => $flagIds, + "extractor" => $extractorFunc, + "params" => array() + ); + $elements = array( + "annotations" => array(), + "relations" => array(), + "lemmas" => array(), + "attributes" => array(), + ); + $extractor_stats = array(); + + // mocking for throw exception emulate + $mockCorpusExporter = $this->getMockBuilder(CorpusExporter::class) + -> disableArgumentCloning() + -> setMethods(array('updateExtractorStats')) + -> getMock(); + $expectedName = $extractorName; + $expectedStats = array(); + $expectedElements = array( + "annotations" => array(), + "relations" => array(), + "lemmas" => array($lemma2), + "attributes" => array(), + ); + $returnedStats = array( + $extractorName => array("annotations"=>0,"relations"=>0,"lemmas"=>1,"attributes"=>0) + ); + + $mockCorpusExporter -> expects($this->once()) + -> method('updateExtractorStats') + -> with($expectedName,$expectedStats,$expectedElements) + -> will($this->returnValue($returnedStats)); + + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($mockCorpusExporter,'runExtractor'); + $protectedMethod->invokeArgs($mockCorpusExporter,array($flags,$report_id,$extractor,&$elements,&$extractor_stats)); + + $expectedElements = array( + "annotations" => [], + "relations"=>[], + "lemmas"=>array($lemma2), + "attributes"=>[] + ); + $this->assertEquals($expectedElements,$elements); + $expectedStats = $returnedStats; + $this->assertEquals($expectedStats,$extractor_stats); + + } // testRunextractorsForExtractorStandardLemmasSetsLemmaFieldsInElementsLemmasSection() + +} // CorpusExporter_part11_Test class + +?> diff --git a/phpunit/tests/engine/include/export/CorpusExporter_part12_Test.php b/phpunit/tests/engine/include/export/CorpusExporter_part12_Test.php new file mode 100644 index 00000000..523280e1 --- /dev/null +++ b/phpunit/tests/engine/include/export/CorpusExporter_part12_Test.php @@ -0,0 +1,332 @@ +virtualDir = vfsStream::setup('root',null,[]); + + } // setUp() + + private function emptyExtractorData() { + + return array("annotations"=>array(), "relations"=>array(), "lemmas"=>array(), "attributes"=>array()); + + } // emptyExtractorData + + private function lemmaData() { + + return array ( 'report_annotation_id' => '2', 'lemma' => 'lemat dodany do okno', 'id' => '2', 'report_id' => '1', 'type_id' => '119', 'type' => 'nam_oth', 'group' => '1', 'from' => '10', 'to' => '13', 'text' => 'okno', 'user_id' => NULL, 'creation_time' => '2022-10-03 08:34:21', 'stage' => 'final', 'source' => 'user', 'annotation_type_id' => '119', 'name' => 'nam_oth', 'description' => 'Nazwy własne niezaklasyfikowane do pozostałych grup (w przypadku braku bardziej szczegółowego typu anotacji w obrębie nam_oth).', 'group_id' => '1', 'annotation_subset_id' => '8', 'level' => '0', 'short_description' => '', 'css' => 'background: lightgreen; border: 1px dashed red; border-bottom: 2px solid red;', 'cross_sentence' => '0', 'shortlist' => '0', 'annotation_id' => NULL, 'annotation_attribute_id' => NULL, 'value' => NULL ); + + } // lemmaData() + + private function annotationWithLemmaData() { + + return array ( 'id' => '2', 'report_id' => '1', 'type_id' => '119', 'from' => '10', 'to' => '13', 'text' => 'okno', 'user_id' => '1', 'creation_time' => '2022-10-03 08:34:21', 'stage' => 'final', 'source' => 'user', 'type' => 'nam_oth', 'group_id' => '1', 'annotation_subset_id' => '8', 'lemma' => 'lemat dodany do okno', 'login' => 'admin', 'screename' => 'Inforex Admin' ); + + } // annotationWithLemmaData() + + private function annotationWoLemmaData() { + + return array ( 'id' => '1', 'report_id' => '1', 'type_id' => '360', 'from' => '6', 'to' => '9', 'text' => 'duże', 'user_id' => '1', 'creation_time' => '2022-10-03 08:07:37', 'stage' => 'final', 'source' => 'user', 'type' => 'nam_adj', 'group_id' => '1', 'annotation_subset_id' => '52', 'lemma' => NULL, 'login' => 'admin', 'screename' => 'Inforex Admin' ); + + } // annotationWoLemmaData() + + public function test_LemmaInAnnotationsTable() { + + // export_document() dumb parameters + $report_id = 1; + $fakeExtractor = array(); + $extractors = array( $fakeExtractor ); + $disamb_only = true; + $extractor_stats = array(); + $lists = array(); + $output_folder = $this->virtualDir->url(); + $subcorpora = ''; + $tagging_method = 'tagger'; + + + + $mockCorpusExporter = $this->getMockBuilder(CorpusExporter::class) + -> disableArgumentCloning() + -> setMethods(array('getFlagsByReportId','getTokenByReportId', + 'getReportTagsByTokens','getReportById', + 'getReportExtById','exportReportContent', + 'updateLists','createIniFile', + 'checkIfAnnotationForLemmaExists', + 'checkIfAnnotationForRelationExists', + //'sortUniqueAnnotationsById', + 'dispatchElements','generateCcl', + 'runExtractor')) + -> getMock(); + + $reportFlags = array('flagnamelowercase'=>array(-1)); + $mockCorpusExporter -> method('getFlagsByReportId') + -> will($this->returnValue($reportFlags)); + $annotations = array(); + $returnedTableList = [$annotations,array(),array(),array()]; + $mockCorpusExporter -> expects($this->once()) + ->method('dispatchElements') + -> will($this->returnValue($returnedTableList)); + $reportTokens = array(); + $mockCorpusExporter -> method('getTokenByReportId') + -> will($this->returnValue($reportTokens)); + $reportTags = array(); + $mockCorpusExporter -> method('getReportTagsByTokens') + -> will($this->returnValue($reportTags)); + $reportContent = "tekst dokumentu raportu"; + $report = array( 'id'=>$report_id, 'content'=>$reportContent, + 'name'=>"report name must exists" ); + $mockCorpusExporter -> method('getReportById') + -> will($this->returnValue($report)); + $fileName = str_pad($report_id,8,'0',STR_PAD_LEFT); + $returnedCcl = new CclExportDocument($report,$reportTokens,$reportTags); + //$returnedCcl -> setFileName($fileName); + $mockCorpusExporter -> expects($this->once()) + ->method('generateCcl') + ->with($report,$reportTokens,$reportTags) + -> will($this->returnValue($returnedCcl)); + + // reflection for acces to private elements + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($mockCorpusExporter,'export_document'); + + // tested call + $protectedMethod->invokeArgs($mockCorpusExporter,array($report_id,$extractors,$disamb_only,&$extractor_stats,&$lists,$output_folder,$subcorpora,$tagging_method)); + + // returned results in $extractor_stats, $lists and export files + + + } // test_LemmaInAnnotationsTable() + +// ===== + + public function testMinimalParameterForExampleExecution() { + // minimal setting for proper execution of mock export_document + + // var_dump(file_get_contents('.xml')); // zwraca zawartość ? + $report_id = 1; + $fakeExtractor = array("extractor" => null, "params"=>array(), "flag_name"=>null, "flag_ids"=>array()); + $extractors = array( $fakeExtractor ); + $disamb_only = true; + $extractor_stats = array(); + $lists = array(); + $output_folder = $this->virtualDir->url(); + $subcorpora = array(1=>'must exists for report[subcorpus_id] index'); + $tagging_method = 'tagger'; + $mockCorpusExporter = $this->getMockBuilder(CorpusExporter::class) + -> disableArgumentCloning() + -> setMethods(array( + 'getFlagsByReportId', // block fetch() error + 'getTokenByReportId', // block fetch() error + 'getReportTagsByTokens', // block fetch() error + 'getReportById', // block fetch() error + 'getReportExtById', // block fetch() error + 'generateCcl', // for proper filename generation + )) + -> getMock(); + $mockCorpusExporter -> method('getTokenByReportId') + -> will($this->returnValue(array())); // block array_column error + // for create proper filename for output files: + $fileName = str_pad($report_id,8,'0',STR_PAD_LEFT); + $report = array('id'=>$report_id, + 'content'=>'content must exists', + 'name'=>"report name must exists", + 'subcorpus_id'=>1, + "date"=>'DATA', + "title"=>'TITLE', + "source"=>'SOURCE', + "author"=>'AUTHOR', + "tokenization"=>'TOKENIZATION', + "format"=>'FORMAT'); + $tokens = array(); $tags = array(); + $ccl = new CclExportDocument($report,$tokens,$tags); + $ccl -> setFileName($fileName); + $mockCorpusExporter + -> expects($this->once()) + -> method('getReportById') + -> with($report_id) + -> will($this->returnValue($report)); + $mockCorpusExporter -> expects($this->once()) + -> method('generateCcl') + -> with($report,array(),null) + -> will($this->returnValue($ccl)); + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($mockCorpusExporter,'export_document'); + $protectedMethod->invokeArgs($mockCorpusExporter,array($report_id,$extractors,$disamb_only,&$extractor_stats,&$lists,$output_folder,$subcorpora,$tagging_method)); + + // possible outputs + $this->assertEquals(array(),$lists); // lists array + $this->assertEquals(array(),$extractor_stats); // extractor_stats array + // 6 files should be created + $file_path_without_ext = $output_folder."/".$fileName; + // INI file + $this->assertTrue(file_exists($file_path_without_ext.'.ini')); + // TXT file + $this->assertTrue(file_exists($file_path_without_ext.'.txt')); + // XML file + $this->assertTrue(file_exists($file_path_without_ext.'.xml')); + // REL.XML file + $this->assertTrue(file_exists($file_path_without_ext.'.rel.xml')); + // JSON file + $this->assertTrue(file_exists($file_path_without_ext.'.json')); + // CONLL file + $this->assertTrue(file_exists($file_path_without_ext.'.conll')); + + //$resultFileContent = file_get_contents($file_path_without_ext.'.xml'); + + } // testMinimalParameterForExampleExecution() + + public function testMainFlowForXMLLemmaExport() { + + $report_id = 1; + $flag_name = 'flag_short_name'; + $flag_id = 1; // -1,...,5 + $fakeExtractor = array( + 'name' => 'extractorNAME', + "flag_name" => $flag_name, + "flag_ids" => array($flag_id), + "extractor" => null, + "params" => array() ); + $extractors = array( $fakeExtractor ); + $disamb_only = true; + $extractor_stats = array(); + $lists = array(); + $output_folder = $this->virtualDir->url(); + $subcorpora = ''; + $tagging_method = 'tagger'; + // emulowane dane z bazy danych + $flags = array( $flag_name => $flag_id ); + $report = array('id'=>$report_id, + "content"=>'To jest duże okno.', + 'name'=>"report name must exists", + 'subcorpus_id'=>1, + "date"=>'DATA', + "title"=>'TITLE', + "source"=>'SOURCE', + "author"=>'AUTHOR', + "tokenization"=>'TOKENIZATION', + "format"=>'FORMAT'); + $tokens = array( + // all fields from DB, enough are "from","to","token_id" + // from,to are offset in content without white chars and tags + array( "from"=>6, "to"=>9, "orth"=>'duże', "eos"=>false, "token_id"=>231, "report_id"=>$report_id ), + array( "from"=>10, "to"=>13, "orth"=>'okno', "eos"=>true, "token_id"=>2314, "report_id"=>$report_id ), + ); + // records for tokens id's above + $tags_by_tokens = array( + 231 => array ( + // must have "disamb","ctag","base_text" + [ "token_tag_id" => "30","token_id"=>"231","disamb"=>"1","ctag_id"=>"25","ctag"=>"CTAG","tagset_id"=>1,"base_id"=>7,"base_text"=>"BASE" ] + ) + ); + $annotations = array( + $this->annotationWoLemmaData(), + $this->annotationWithLemmaData() + ); + $relations = array(); + $lemmas = array( $this->lemmaData() ); + $attributes = array(); + $extractors[0]["extractor"] = + function($report_id, $params, &$extractor_elements) { + $extractor_elements= array( + "relations"=>[], + "attributes"=>[], + "annotations" => array( + $this->annotationWoLemmaData(), + $this->annotationWithLemmaData() ), + "lemmas" => array( $this->lemmaData() )); + }; + + $mockCorpusExporter = $this->getMockBuilder(CorpusExporter::class) + -> disableArgumentCloning() + -> setMethods(array( + 'getFlagsByReportId', // block fetch() error + 'getTokenByReportId', // block fetch() error + 'getReportTagsByTokens', // block fetch() error + 'getReportById', // block fetch() error + 'getReportExtById', // block fetch() error + )) -> getMock(); + $mockCorpusExporter -> expects($this->once()) + -> method('getTokenByReportId') + -> with($report_id) + -> will($this->returnValue($tokens)); // block array_column error + // === dodane do generowania lematów + // wygenerowne flagi - używane tylko w ekstraktorze + $mockCorpusExporter -> expects($this->once()) + -> method('getFlagsByReportId') + -> with($report_id) + -> will($this->returnValue($flags)); + // emulacja getReportById - dla generateCcl + $mockCorpusExporter -> expects($this->once()) + -> method('getReportById') + -> with($report_id) + -> will($this->returnValue($report)) + ; + // emulacja getReportTagsByTokens - dla generate Ccl + $token_ids = array(231,2314); // array_column($tokens, 'token_id') + $mockCorpusExporter -> expects($this->once()) + -> method('getReportTagsByTokens') + -> with($report_id,$token_ids,$disamb_only,$tagging_method) + -> will($this->returnValue($tags_by_tokens)) + ; + + // reflection for acces to private elements + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($mockCorpusExporter,'export_document'); + + // tested call + $protectedMethod->invokeArgs($mockCorpusExporter,array($report_id,$extractors,$disamb_only,&$extractor_stats,&$lists,$output_folder,$subcorpora,$tagging_method)); + + // check results in XML file + $fileName = str_pad($report_id,8,'0',STR_PAD_LEFT); + $resultFileName = $output_folder.'/'.$fileName.".xml"; + $this->assertTrue(file_exists($resultFileName)); + $resultFileContent = file_get_contents($resultFileName); + //var_dump($resultFileContent); + // prefix for proper XML + $expectedXmlContentPrefix = 'assertRegexp('@'.$expectedXmlContentPrefix."@",$resultFileContent); + // annotacja bez lematu ( lemma=NULL ) + $expectedAnnWithoutLemmaLine = '1'; + $this->assertRegexp('@'.$expectedAnnWithoutLemmaLine.'@m',$resultFileContent); + // annotacja towarzysząca lematowi + $expectedAnnWithLemmaLine = '2'; + $this->assertRegexp('@'.$expectedAnnWithLemmaLine.'@m',$resultFileContent); + // lemat - z pozycji w $lemmas + $expectedLemmaLine = 'lemat dodany do okno'; + $this->assertRegexp('@'.$expectedLemmaLine.'@m',$resultFileContent); + // lemma line after anno line in export XML + $expectedAnnWithLemmaLines = +'2'.'\s*'.'lemat dodany do okno'; + $this->assertRegexp('@'.$expectedAnnWithLemmaLines.'@m',$resultFileContent); + + // check results in JSON file + $resultFileName = $output_folder.'/'.$fileName.".json"; + $resultFileContent = file_get_contents($resultFileName); + //var_dump($resultFileContent); + // annotacja bez lematu ( lemma=NULL ) + $expectedAnnWithoutLemmaPattern = '@' + .'"annotations": '.'.+' // w sekcji po słowie 'annotations' + .'\{.+"from": "6",.+"to": "9",[^\}]*' // w tokenie na poz. 6-9 + .'"lemma": null,' // jest wpis o lemacie + .'.*\}'.'@s'; + $this->assertRegexp($expectedAnnWithoutLemmaPattern,$resultFileContent); + // annotacja z lematem ( "lemat dodany do okno" ) + $expectedAnnWithLemmaPattern = '@' + .'"annotations": '.'.+' // w sekcji po słowie 'annotations' + .'\{.+"from": "10",.+"to": "13",[^\}]*' // w tokenie na poz. 10-13 + .'"lemma": "lemat dodany do okno",' // jest wpis o lemacie + .'.*\}'.'@s'; + $this->assertRegexp($expectedAnnWithLemmaPattern,$resultFileContent); + + + }// testMainFlowForXMLLemmaExport() + +} // CorpusExporter_part12_Test class + +?> diff --git a/phpunit/tests/engine/include/export/CorpusExporter_part13_Test.php b/phpunit/tests/engine/include/export/CorpusExporter_part13_Test.php new file mode 100644 index 00000000..4d12489d --- /dev/null +++ b/phpunit/tests/engine/include/export/CorpusExporter_part13_Test.php @@ -0,0 +1,449 @@ +virtualDir = vfsStream::setup('root',null,[]); + $this->commonDataSetup(); + + } // setUp() + + private function emptyExtractorData() { + + return array("annotations"=>array(), "relations"=>array(), "lemmas"=>array(), "attributes"=>array()); + + } // emptyExtractorData + + private function reportData($report_id=1) { + + // full filled record + return array( "id"=>$report_id,"corpora"=>1,"date"=>'DATA',"title"=>'TITLE',"source"=>'SOURCE',"author"=>'AUTHOR',"content"=>'To jest duże okno.',"type"=>1,"status"=>1,"user_id"=>1,"subcorpus_id"=>1,"tokenization"=>'TOKENIZATION',"format_id"=>'',"lang"=>'LANG',"filename"=>'FILENAME',"parent_report_id"=>1,"deleted"=>0); + // "format"='' generate as default format_id=1 format = 'xml' + + } // reportData() + + private function lemmaData() { + + return array ( 'report_annotation_id' => '2', 'lemma' => 'lemat dodany do okno', 'id' => '2', 'report_id' => '1', 'type_id' => '119', 'type' => 'nam_oth', 'group' => '1', 'from' => '10', 'to' => '13', 'text' => 'okno', 'user_id' => NULL, 'creation_time' => '2022-10-03 08:34:21', 'stage' => 'final', 'source' => 'user', 'annotation_type_id' => '119', 'name' => 'nam_oth', 'description' => 'Nazwy własne niezaklasyfikowane do pozostałych grup (w przypadku braku bardziej szczegółowego typu anotacji w obrębie nam_oth).', 'group_id' => '1', 'annotation_subset_id' => '8', 'level' => '0', 'short_description' => '', 'css' => 'background: lightgreen; border: 1px dashed red; border-bottom: 2px solid red;', 'cross_sentence' => '0', 'shortlist' => '0', 'annotation_id' => NULL, 'annotation_attribute_id' => NULL, 'value' => NULL ); + + } // lemmaData() + + private function annotationStandardExtractorRecord($report_id=1,$annotation_id=1,$from=6,$to=9,$type='nam_adj') { + + // fullfilled + // as generated by annotation_set_id or annotation_subset_id + // extractor ( all fields from reports_annotations, + // annotation_types and annotation_id, annotation_attribute_id, + // attr_user_id( cast from user_id), prop(cast from value ) + // from report_annotations_attributes + return array( 'id' => $annotation_id, 'report_id' => $report_id, 'type_id' => '360', 'type'=>$type, 'group'=>'1', 'from' => $from, 'to' => $to, 'text' => 'duże', 'user_id' => '1', 'creation_time' => '2022-10-03 08:07:37', 'stage' => 'final', 'source' => 'user', 'annotation_type_id'=>'360', 'name'=>$type, 'description'=>'DESCRIPTION', 'group_id' => '1', 'annotation_subset_id' => '52', 'level'=>0, 'short_description'=>'SHORT_DESCRIPTION', 'css'=>'CSS', 'cross_sentence'=>'CROSS_SENTENCE', 'shortlist'=>'SHORTLIST', 'annotation_id'=>$annotation_id, 'annotation_attribute_id'=>721, 'attr_user_id'=>'1', 'prop'=>'ATRYBUT' + ); + + } // annotationStandardRecord + + private function annotationCustomExtractorRecord($report_id=1,$annotation_id=1,$from=6,$to=9,$type='nam_adj',$lemma='LEMMA') { + + // fullfilled + // as generated by "annotation=" extractor ( all fields from + // reports_annotations_optimized, from annotation_types only + // type( cast from name ), group_id, annotation_subset_id, + // lemma from reports_annotations_lemma, from users only + // login and screename + return array( 'id' => $annotation_id, 'report_id' => $report_id, 'type_id' => '360', 'from' => $from, 'to' => $to, 'text' => 'duże', 'user_id' => '1', 'creation_time' => '2022-10-03 08:07:37', 'stage' => 'final', 'source' => 'user', 'type'=>$type, 'group_id' => '1', 'annotation_subset_id' => '52', + // 'lemma'=>$lemma, - 'lemma' field is now removed by ekstractor + 'login'=>'LOGIN', 'screename'=>'SCREENAME'); + + } // annotationCustomExtractorRecord() + + private function getMinimalExtractorData($flag_name='flag_short_name',$flag_id=1) { + return array( 'name' => 'extractorNAME', "flag_name" => $flag_name, "flag_ids" => array($flag_id), "extractor" => null, "params" => array() ); + + } // getMinimalExtractorData() + + private function getTokenData($report_id=1,$token_id=231,$from=6,$to=9) { + + return array( "from"=>$from, "to"=>$to, "orth"=>'duże', "eos"=>false, "token_id"=>$token_id, "report_id"=>$report_id ); + + } // getTokenData() + + private function getTagsData($token_id) { + + return array ( "token_tag_id" => "30","token_id"=>$token_id,"disamb"=>"1","ctag_id"=>"25","ctag"=>"CTAG","tagset_id"=>1,"base_id"=>7,"base_text"=>"BASE" ); + + } // getTokenData() + + private function commonDataSetup($report_id=1) { + + $this->report_id = $report_id; + $flag_name = 'flag_short_name'; + $flag_id = 1; // -1,...,5 + $this->extractors = array( $this->getMinimalExtractorData($flag_name,$flag_id) ); + $this->disamb_only = true; + $this->extractor_stats = array(); + $this->lists = array(); + $this->output_folder = $this->virtualDir->url(); + $this->subcorpora = ''; + $this->tagging_method = 'tagger'; + // emulowane dane z bazy danych + $flags = array( $flag_name => $flag_id ); + $report = $this->reportData($report_id); + $tokens = array( + $this->getTokenData($report_id,231,6,9), $this->getTokenData($report_id,2314,10,13) + ); + $tags_by_tokens = array( 231 => array ( $this->getTagsData(231) ) ); + + $this->mockCorpusExporter = $this->getMockBuilder(CorpusExporter::class) + -> disableArgumentCloning() + -> setMethods(array( + 'getFlagsByReportId', // block fetch() error + 'getTokenByReportId', // block fetch() error + 'getReportTagsByTokens', // block fetch() error + 'getReportById', // block fetch() error + 'getReportExtById', // block fetch() error + )) -> getMock(); + $this->mockCorpusExporter -> expects($this->once()) + -> method('getTokenByReportId') + -> with($report_id) + -> will($this->returnValue($tokens)); // block array_column error + // === dodane do generowania lematów + // wygenerowne flagi - używane tylko w ekstraktorze + $this->mockCorpusExporter -> expects($this->once()) + -> method('getFlagsByReportId') + -> with($report_id) + -> will($this->returnValue($flags)); + // emulacja getReportById - dla generateCcl + $this->mockCorpusExporter -> expects($this->once()) + -> method('getReportById') + -> with($report_id) + -> will($this->returnValue($report)) + ; + // emulacja getReportTagsByTokens - dla generate Ccl + $token_ids = array(231,2314); // array_column($tokens, 'token_id') + $this->mockCorpusExporter -> expects($this->once()) + -> method('getReportTagsByTokens') + -> with($report_id,$token_ids,$this->disamb_only,$this->tagging_method) + -> will($this->returnValue($tags_by_tokens)) + ; + + // reflection for acces to private elements + $this->protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($this->mockCorpusExporter,'export_document'); + + $this->fileName = str_pad($report_id,8,'0',STR_PAD_LEFT); + + } // commonDataSetup() + +// ===== + + public function testStandardLemmaExtractorOnlyWritesNoLemmaInExportOutputs() { + + // Standard extractor lemma_annotation_set_id + // or lemma_annotation_subset_id only + $this->extractors[0]["extractor"] = // set extractor function() + function($report_id, $params, &$extractor_elements) { + $extractor_elements= array( + "relations"=>[], + "attributes"=>[], + "annotations" => array(), + "lemmas" => array( $this->lemmaData() )); + }; + + // tested call + $this->protectedMethod->invokeArgs($this->mockCorpusExporter,array($this->report_id,$this->extractors,$this->disamb_only,&$this->extractor_stats,&$this->lists,$this->output_folder,$this->subcorpora,$this->tagging_method)); + + // check results in XML file + $resultFileName = $this->output_folder.'/'.$this->fileName.".xml"; + $this->assertTrue(file_exists($resultFileName)); + $resultFileContent = file_get_contents($resultFileName); + // no lemma phrase in export output + $lemmaPattern = '@lemma@s'; + $this->assertEquals(0,preg_match($lemmaPattern,$resultFileContent)); + + // check results in JSON file + $resultFileName = $this->output_folder.'/'.$this->fileName.".json"; + $this->assertTrue(file_exists($resultFileName)); + $resultFileContent = file_get_contents($resultFileName); + // no lemma phrase in export output + $lemmaPattern = '@lemma@s'; + $this->assertEquals(0,preg_match($lemmaPattern,$resultFileContent)); + + } // testStandardLemmaExtractorOnlyWritesNoLemmaInExportOutputs() + + public function testStandardAnnotationAndLemmaExtractorWritesLemmaInExportOutputs() { + + // Standard extractor lemma_annotation_set_id + // or lemma_annotation_subset_id only + // with coresponding annotation + $this->extractors[0]["extractor"] = // set extractor function() + function($report_id, $params, &$extractor_elements) { + $extractor_elements= array( + "relations"=>[], + "attributes"=>[], + "annotations" => array( + $this->annotationStandardExtractorRecord($report_id,2,10,13,'nam_oth') + ), + "lemmas" => array( $this->lemmaData() )); + }; + + // tested call + $this->protectedMethod->invokeArgs($this->mockCorpusExporter,array($this->report_id,$this->extractors,$this->disamb_only,&$this->extractor_stats,&$this->lists,$this->output_folder,$this->subcorpora,$this->tagging_method)); + + // check results in XML file + $resultFileName = $this->output_folder.'/'.$this->fileName.".xml"; + $this->assertTrue(file_exists($resultFileName)); + $resultFileContent = file_get_contents($resultFileName); + // lemat - w pozycji tokenu ( "lemat dodany do okno" ) + $expectedLemmaLine = 'lemat dodany do okno'; + $this->assertRegexp('@'.$expectedLemmaLine.'@m',$resultFileContent); + // lemat wpisany w tag odpowiadajacej annotacji + $expectedAnnWithLemmaLines = +'2'.'\s*'.'lemat dodany do okno'; + $this->assertRegexp('@'.$expectedAnnWithLemmaLines.'@m',$resultFileContent); + + // check results in JSON file + $resultFileName = $this->output_folder.'/'.$this->fileName.".json"; + $this->assertTrue(file_exists($resultFileName)); + $resultFileContent = file_get_contents($resultFileName); + // in .json format there are not lemma in chunks + // only link to annotation + // lemat w tabeli annotacji ( "lemat dodany do okno" ) + $expectedAnnWithLemmaPattern = '@' + .'"annotations": '.'.+' // w sekcji po słowie 'annotations' + .'\{.+"from": 10,.+"to": 13,[^\}]*' // w tokenie na poz. 10-13 + .'"lemma": "lemat dodany do okno"' // jest wpis o lemacie + .'.*\}'.'@s'; + $this->assertRegexp($expectedAnnWithLemmaPattern,$resultFileContent); + + } // testStandardAnnotationAndLemmaExtractorWritesLemmaInExportOutputs() + + public function testStandardAnnotationExtractorWritesNoLemmaInExportOutputs() { + + // Standard extractor annotation_set_id or annotation_subset_id only + $this->extractors[0]["extractor"] = // set extractor function() + function($report_id, $params, &$extractor_elements) { + $extractor_elements= array( + "relations"=>[], + "attributes"=>[], + "annotations" => array( + // standard annotation exports has no lemma fields + $this->annotationStandardExtractorRecord($report_id,1,6,9,'nam_adj'), + $this->annotationStandardExtractorRecord($report_id,2,10,13,'nam_oth') + ), + "lemmas" => array() + //"lemmas" => array( $this->lemmaData() ) + ); + }; + + // tested call + $this->protectedMethod->invokeArgs($this->mockCorpusExporter,array($this->report_id,$this->extractors,$this->disamb_only,&$this->extractor_stats,&$this->lists,$this->output_folder,$this->subcorpora,$this->tagging_method)); + + // check results in XML file + $resultFileName = $this->output_folder.'/'.$this->fileName.".xml"; + $this->assertTrue(file_exists($resultFileName)); + $resultFileContent = file_get_contents($resultFileName); + // no lemma phrase in export output + $lemmaPattern = '@lemma@s'; + $this->assertEquals(0,preg_match($lemmaPattern,$resultFileContent)); + + // check results in JSON file + $resultFileName = $this->output_folder.'/'.$this->fileName.".json"; + $this->assertTrue(file_exists($resultFileName)); + $resultFileContent = file_get_contents($resultFileName); + // no lemma phrase in export output + $lemmaPattern = '@lemma@s'; + $this->assertEquals(0,preg_match($lemmaPattern,$resultFileContent)); + + }// testStandardAnnotationExtractorWritesNoLemmaInExportOutputs() + + public function testCustomLemmaExtractorOnlyWritesNoLemmaInExportOutputs() { + + // Custom extractor annotation=lemma_set_id + // or annotation=lemma_subset_id only + $this->extractors[0]["extractor"] = // set extractor function() + + function($report_id, $params, &$extractor_elements) { + $extractor_elements= array( + "relations"=>[], + "attributes"=>[], + "annotations" => array(), + "lemmas" => array( $this->lemmaData() )); + }; + + // tested call + $this->protectedMethod->invokeArgs($this->mockCorpusExporter,array($this->report_id,$this->extractors,$this->disamb_only,&$this->extractor_stats,&$this->lists,$this->output_folder,$this->subcorpora,$this->tagging_method)); + + // check results in XML file + $resultFileName = $this->output_folder.'/'.$this->fileName.".xml"; + $this->assertTrue(file_exists($resultFileName)); + $resultFileContent = file_get_contents($resultFileName); + // no lemma phrase in export output + $lemmaPattern = '@lemma@s'; + $this->assertEquals(0,preg_match($lemmaPattern,$resultFileContent)); + + // check results in JSON file + $resultFileName = $this->output_folder.'/'.$this->fileName.".json"; + $this->assertTrue(file_exists($resultFileName)); + $resultFileContent = file_get_contents($resultFileName); + // no lemma phrase in export output + $lemmaPattern = '@lemma@s'; + $this->assertEquals(0,preg_match($lemmaPattern,$resultFileContent)); + + }// testCustomLemmaExtractorOnlyWritesNoLemmaInExportOutputs + + public function testCustomAnnotationAndLemmaExtractorWritesLemmaInExportOutputs() { + + // Custom extractor annotation=annotation_set_id;lemma__set_id + // or annotation=annotation_subset_id;lemma_subset_id + // with coresponding annotation + $this->extractors[0]["extractor"] = // set extractor function() + function($report_id, $params, &$extractor_elements) { + $extractor_elements= array( + "relations"=>[], + "attributes"=>[], + "annotations" => array( + $this->annotationCustomExtractorRecord($report_id,2,10,13,'nam_oth',"lemat dodany do okno") + ), + "lemmas" => array( $this->lemmaData() )); + }; + + // tested call + $this->protectedMethod->invokeArgs($this->mockCorpusExporter,array($this->report_id,$this->extractors,$this->disamb_only,&$this->extractor_stats,&$this->lists,$this->output_folder,$this->subcorpora,$this->tagging_method)); + + // check results in XML file + $resultFileName = $this->output_folder.'/'.$this->fileName.".xml"; + $this->assertTrue(file_exists($resultFileName)); + $resultFileContent = file_get_contents($resultFileName); + // lemat - w pozycji tokenu ( "lemat dodany do okno" ) + $expectedLemmaLine = 'lemat dodany do okno'; + $this->assertRegexp('@'.$expectedLemmaLine.'@m',$resultFileContent); + + // lemat wpisany w tag odpowiadajacej annotacji + $expectedAnnWithLemmaLines = +'2'.'\s*'.'lemat dodany do okno'; + $this->assertRegexp('@'.$expectedAnnWithLemmaLines.'@m',$resultFileContent); + + // check results in JSON file + $resultFileName = $this->output_folder.'/'.$this->fileName.".json"; + $this->assertTrue(file_exists($resultFileName)); + $resultFileContent = file_get_contents($resultFileName); + // lemat w pozycji tokena w chunks[] + // in .json format there are not lemma in chunks + // only link to annotation + // lemat w tabeli annotacji ( "lemat dodany do okno" ) + $expectedAnnWithLemmaPattern = '@' + .'"annotations": '.'.+' // w sekcji po słowie 'annotations' + .'\{.+"from": 10,.+"to": 13,[^\}]*' // w tokenie na poz. 10-13 + .'"lemma": "lemat dodany do okno"' // jest wpis o lemacie + .'.*\}'.'@s'; + $this->assertRegexp($expectedAnnWithLemmaPattern,$resultFileContent); + + } // testCustomAnnotationAndLemmaExtractorWritesLemmaInExportOutputs() + + public function testCustomAnnotationExtractorWritesNoLemmaInExportOutputs() { + + // Custom extractor annotation=annotation_set_id + // or annotation=annotation_subset_id only + $this->extractors[0]["extractor"] = // set extractor function() + function($report_id, $params, &$extractor_elements) { + $extractor_elements= array( + "relations"=>[], + "attributes"=>[], + "annotations" => array( + // standard annotation exports has no lemma fields + $this->annotationCustomExtractorRecord($report_id,1,6,9,'nam_adj',null), + $this->annotationCustomExtractorRecord($report_id,2,10,13,'nam_oth',"lemat dodany do okno") + ), + "lemmas" => array() + ); + }; + + // tested call + $this->protectedMethod->invokeArgs($this->mockCorpusExporter,array($this->report_id,$this->extractors,$this->disamb_only,&$this->extractor_stats,&$this->lists,$this->output_folder,$this->subcorpora,$this->tagging_method)); + + // check results in XML file + $resultFileName = $this->output_folder.'/'.$this->fileName.".xml"; + $this->assertTrue(file_exists($resultFileName)); + $resultFileContent = file_get_contents($resultFileName); + // no lemma phrase in export output + $lemmaPattern = '@lemma@s'; + $this->assertEquals(0,preg_match($lemmaPattern,$resultFileContent)); + + // check results in JSON file + $resultFileName = $this->output_folder.'/'.$this->fileName.".json"; + $this->assertTrue(file_exists($resultFileName)); + $resultFileContent = file_get_contents($resultFileName); + // no lemma phrase in export output + $lemmaPattern = '@lemma@s'; + $this->assertEquals(0,preg_match($lemmaPattern,$resultFileContent)); + + } // testCustomAnnotationExtractorWritesNoLemmaInExportOutputs() + + public function testCustomExportManuallyModifiedWorksAsOldVersion() { + + $this->extractors[0]["extractor"] = // set extractor function() + function($report_id, $params, &$extractor_elements) { + $anno1 = $this->annotationCustomExtractorRecord($report_id,1,6,9,'nam_adj',null); + $anno1['lemma'] = null; // lemma must be add manually now + $anno2 = $this->annotationCustomExtractorRecord($report_id,2,10,13,'nam_oth',"lemat dodany do okno"); + $anno2['lemma'] = "lemat dodany do okno"; // lemma must be add manually now + $extractor_elements= array( + "relations"=>[], + "attributes"=>[], + "annotations" => array( $anno1,$anno2 ), + "lemmas" => array( $this->lemmaData() )); + }; + + // tested call + $this->protectedMethod->invokeArgs($this->mockCorpusExporter,array($this->report_id,$this->extractors,$this->disamb_only,&$this->extractor_stats,&$this->lists,$this->output_folder,$this->subcorpora,$this->tagging_method)); + + // check results in XML file + $resultFileName = $this->output_folder.'/'.$this->fileName.".xml"; + $this->assertTrue(file_exists($resultFileName)); + $resultFileContent = file_get_contents($resultFileName); + // prefix for proper XML + $expectedXmlContentPrefix = 'assertRegexp('@'.$expectedXmlContentPrefix."@",$resultFileContent); + // annotacja bez lematu ( lemma=NULL ) + $expectedAnnWithoutLemmaLine = '1'; + $this->assertRegexp('@'.$expectedAnnWithoutLemmaLine.'@m',$resultFileContent); + // annotacja towarzysząca lematowi + $expectedAnnWithLemmaLine = '2'; + $this->assertRegexp('@'.$expectedAnnWithLemmaLine.'@m',$resultFileContent); + // lemat - z pozycji w $lemmas + $expectedLemmaLine = 'lemat dodany do okno'; + $this->assertRegexp('@'.$expectedLemmaLine.'@m',$resultFileContent); + // lemma line after anno line in export XML + $expectedAnnWithLemmaLines = +'2'.'\s*'.'lemat dodany do okno'; + $this->assertRegexp('@'.$expectedAnnWithLemmaLines.'@m',$resultFileContent); + + // check results in JSON file + $resultFileName = $this->output_folder.'/'.$this->fileName.".json"; + $resultFileContent = file_get_contents($resultFileName); + // annotacja bez lematu ( lemma=NULL ) + $expectedAnnWithoutLemmaPattern = '@' + .'"annotations": '.'.+' // w sekcji po słowie 'annotations' + .'\{.+"from": 6,.+"to": 9,[^\}]*' // w tokenie na poz. 6-9 + .'"lemma": null' // jest wpis o lemacie + .'.*\}'.'@s'; + $this->assertRegexp($expectedAnnWithoutLemmaPattern,$resultFileContent); + // annotacja z lematem ( "lemat dodany do okno" ) + $expectedAnnWithLemmaPattern = '@' + .'"annotations": '.'.+' // w sekcji po słowie 'annotations' + .'\{.+"from": 10,.+"to": 13,[^\}]*' // w tokenie na poz. 10-13 + .'"lemma": "lemat dodany do okno"' // jest wpis o lemacie + .'.*\}'.'@s'; + $this->assertRegexp($expectedAnnWithLemmaPattern,$resultFileContent); + + }// testCustomExport() + +} // CorpusExporter_part13_Test class + +?> diff --git a/phpunit/tests/engine/include/export/CorpusExporter_part1_Test.php b/phpunit/tests/engine/include/export/CorpusExporter_part1_Test.php index a5247975..2842f505 100644 --- a/phpunit/tests/engine/include/export/CorpusExporter_part1_Test.php +++ b/phpunit/tests/engine/include/export/CorpusExporter_part1_Test.php @@ -90,19 +90,21 @@ private function export_document($disamb_only,$tagging_method) ) // tokens ); - $dbEmu->addReportsDB($report_id,$documentDBData); + $dbEmu->addReportsDB($report_id,$documentDBData); // do test... global $db; $db = $dbEmu; - $ce = new CorpusExporter_mock(); + $ce = new CorpusExporter(); + $extractor_stats = array(); // this will change // $extractors is var parameter, but shouldn't change $extractors = $extractorObj->getExtractorsTable(); $expectedExtractors = $extractors; - $ce->mock_export_document($report_id,$extractors,$disamb_only,$extractor_stats,$lists,$this->virtualDir->url(),$subcorpora,$tagging_method); + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($ce,'export_document'); + $protectedMethod->invokeArgs($ce,array($report_id,$extractors,$disamb_only,&$extractor_stats,&$lists,$this->virtualDir->url(),$subcorpora,$tagging_method)); // check results in variables and files $this->assertEquals($expectedExtractors,$extractors); diff --git a/phpunit/tests/engine/include/export/CorpusExporter_part2_Test.php b/phpunit/tests/engine/include/export/CorpusExporter_part2_Test.php index 8647e138..818d67b6 100644 --- a/phpunit/tests/engine/include/export/CorpusExporter_part2_Test.php +++ b/phpunit/tests/engine/include/export/CorpusExporter_part2_Test.php @@ -93,13 +93,14 @@ private function export_document($disamb_only,$tagging_method) global $db; $db = $dbEmu; - $ce = new CorpusExporter_mock(); + $ce = new CorpusExporter(); $extractor_stats = array(); // this will change // $extractors is var parameter, but shouldn't change $extractors = $extractorObj->getExtractorsTable(); $expectedExtractors = $extractors; - $ce->mock_export_document($report_id,$extractors,$disamb_only,$extractor_stats,$lists,$this->virtualDir->url(),$subcorpora,$tagging_method); + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($ce,'export_document'); + $protectedMethod->invokeArgs($ce,array($report_id,$extractors,$disamb_only,&$extractor_stats,&$lists,$this->virtualDir->url(),$subcorpora,$tagging_method)); // check results in variables and files $this->assertEquals($expectedExtractors,$extractors); diff --git a/phpunit/tests/engine/include/export/CorpusExporter_part3_Test.php b/phpunit/tests/engine/include/export/CorpusExporter_part3_Test.php index c788a00c..4fd12862 100644 --- a/phpunit/tests/engine/include/export/CorpusExporter_part3_Test.php +++ b/phpunit/tests/engine/include/export/CorpusExporter_part3_Test.php @@ -96,14 +96,15 @@ private function export_document($disamb_only,$tagging_method) global $db; $db = $dbEmu; - $ce = new CorpusExporter_mock(); + $ce = new CorpusExporter(); $output_folder = $this->virtualDir->url(); $extractor_stats = array(); // this will change // $extractors is var parameter, but shouldn't change $extractors = $extractorObj->getExtractorsTable(); $expectedExtractors = $extractors; - $ce->mock_export_document($report_id,$extractors,$disamb_only,$extractor_stats,$lists,$output_folder,$subcorpora,$tagging_method); + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($ce,'export_document'); + $protectedMethod->invokeArgs($ce,array($report_id,$extractors,$disamb_only,&$extractor_stats,&$lists,$output_folder,$subcorpora,$tagging_method)); // check results in variables and files $this->assertEquals($expectedExtractors,$extractors); diff --git a/phpunit/tests/engine/include/export/CorpusExporter_part4_Test.php b/phpunit/tests/engine/include/export/CorpusExporter_part4_Test.php index d952ff73..941ac7f9 100644 --- a/phpunit/tests/engine/include/export/CorpusExporter_part4_Test.php +++ b/phpunit/tests/engine/include/export/CorpusExporter_part4_Test.php @@ -96,14 +96,15 @@ private function export_document($disamb_only,$tagging_method) global $db; $db = $dbEmu; - $ce = new CorpusExporter_mock(); + $ce = new CorpusExporter(); $output_folder = $this->virtualDir->url(); $extractor_stats = array(); // this will change // $extractors is var parameter, but shouldn't change $extractors = $extractorObj->getExtractorsTable(); $expectedExtractors = $extractors; - $ce->mock_export_document($report_id,$extractors,$disamb_only,$extractor_stats,$lists,$output_folder,$subcorpora,$tagging_method); + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($ce,'export_document'); + $protectedMethod->invokeArgs($ce,array($report_id,$extractors,$disamb_only,&$extractor_stats,&$lists,$output_folder,$subcorpora,$tagging_method)); // check results in variables and files $this->assertEquals($expectedExtractors,$extractors); diff --git a/phpunit/tests/engine/include/export/CorpusExporter_part5_Test.php b/phpunit/tests/engine/include/export/CorpusExporter_part5_Test.php index 3eea0511..5e83d34b 100644 --- a/phpunit/tests/engine/include/export/CorpusExporter_part5_Test.php +++ b/phpunit/tests/engine/include/export/CorpusExporter_part5_Test.php @@ -50,8 +50,8 @@ private function export_document($disamb_only,$tagging_method) $extractorObj = new MockedExtractor($extractorParameters["FlagName"],$extractorParameters["FlagValues"],$extractorParameters["Name"],$extractorParameters["Parameters"]); // $lemmas = DbReportAnnotationLemma::getLemmasBySets(array($report_id), $params); $extractorData = array( - array( "reports_annotation_id"=>1, "lemma"=>'lemma annotacji 1' ), - array( "reports_annotation_id"=>100, "lemma"=>'lemma annotacji 100'), + array( "reports_annotation_id"=>1, "lemma"=>'lemma annotacji 1', "id"=>12345, "group_id"=>1, "name"=>'NAME', "from"=>0, "to"=>4, "type"=>'TYPE' ), + array( "reports_annotation_id"=>100, "lemma"=>'lemma annotacji 100', "id"=>12346, "group_id"=>1, "name"=>'NAME', "from"=>5, "to"=>13, "type"=>'TYPE' ), ); $extractorObj->setExtractorReturnedData('lemmas',$extractorData); @@ -96,14 +96,15 @@ private function export_document($disamb_only,$tagging_method) global $db; $db = $dbEmu; - $ce = new CorpusExporter_mock(); + $ce = new CorpusExporter(); $output_folder = $this->virtualDir->url(); $extractor_stats = array(); // this will change // $extractors is var parameter, but shouldn't change $extractors = $extractorObj->getExtractorsTable(); $expectedExtractors = $extractors; - $ce->mock_export_document($report_id,$extractors,$disamb_only,$extractor_stats,$lists,$output_folder,$subcorpora,$tagging_method); + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($ce,'export_document'); + $protectedMethod->invokeArgs($ce,array($report_id,$extractors,$disamb_only,&$extractor_stats,&$lists,$output_folder,$subcorpora,$tagging_method)); // check results in variables and files $this->assertEquals($expectedExtractors,$extractors); @@ -127,6 +128,8 @@ private function checkFiles($report_id,$disambOnly,$tagging_method,$reportData,$ $expectedBaseFileName = $this->virtualDir->url().'/'.str_pad($report_id,8,'0',STR_PAD_LEFT); $scl=new SimpleCcl($reportData,$tagging_method,$disambOnly); + // if no annotations, there are no lemmas + //$scl->addLemmas($extractorData); //checkConllFile $expectedContent = $scl->toCONLL(); diff --git a/phpunit/tests/engine/include/export/CorpusExporter_part6_Test.php b/phpunit/tests/engine/include/export/CorpusExporter_part6_Test.php index 986ef957..e28bc8c6 100644 --- a/phpunit/tests/engine/include/export/CorpusExporter_part6_Test.php +++ b/phpunit/tests/engine/include/export/CorpusExporter_part6_Test.php @@ -50,8 +50,8 @@ private function export_document($disamb_only,$tagging_method) $extractorObj = new MockedExtractor($extractorParameters["FlagName"],$extractorParameters["FlagValues"],$extractorParameters["Name"],$extractorParameters["Parameters"]); // $lemmas = DbReportAnnotationLemma::getLemmasBySubsets(array($report_id), $params); $extractorData = array( - array( "reports_annotation_id"=>1, "lemma"=>'lemma annotacji 1' ), - array( "reports_annotation_id"=>100, "lemma"=>'lemma annotacji 100'), + array( "reports_annotation_id"=>1, "lemma"=>'lemma annotacji 1', "id"=>12345, "group_id"=>1, "name"=>'NAME', "from"=>0, "to"=>4, "type"=>'TYPE' ), + array( "reports_annotation_id"=>100, "lemma"=>'lemma annotacji 100', "id"=>12346, "group_id"=>1, "name"=>'NAME', "from"=>5, "to"=>13, "type"=>'TYPE' ), ); $extractorObj->setExtractorReturnedData('lemmas',$extractorData); @@ -96,14 +96,15 @@ private function export_document($disamb_only,$tagging_method) global $db; $db = $dbEmu; - $ce = new CorpusExporter_mock(); + $ce = new CorpusExporter(); $output_folder = $this->virtualDir->url(); $extractor_stats = array(); // this will change // $extractors is var parameter, but shouldn't change $extractors = $extractorObj->getExtractorsTable(); $expectedExtractors = $extractors; - $ce->mock_export_document($report_id,$extractors,$disamb_only,$extractor_stats,$lists,$output_folder,$subcorpora,$tagging_method); + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($ce,'export_document'); + $protectedMethod->invokeArgs($ce,array($report_id,$extractors,$disamb_only,&$extractor_stats,&$lists,$output_folder,$subcorpora,$tagging_method)); // check results in variables and files $this->assertEquals($expectedExtractors,$extractors); @@ -127,6 +128,8 @@ private function checkFiles($report_id,$disambOnly,$tagging_method,$reportData,$ $expectedBaseFileName = $this->virtualDir->url().'/'.str_pad($report_id,8,'0',STR_PAD_LEFT); $scl=new SimpleCcl($reportData,$tagging_method,$disambOnly); + // if no annotations, there are not lemmas + //$scl->addLemmas($extractorData); //checkConllFile $expectedContent = $scl->toCONLL(); diff --git a/phpunit/tests/engine/include/export/CorpusExporter_part7_Test.php b/phpunit/tests/engine/include/export/CorpusExporter_part7_Test.php index 247edd0d..cbcee6fc 100644 --- a/phpunit/tests/engine/include/export/CorpusExporter_part7_Test.php +++ b/phpunit/tests/engine/include/export/CorpusExporter_part7_Test.php @@ -96,14 +96,15 @@ private function export_document($disamb_only,$tagging_method) global $db; $db = $dbEmu; - $ce = new CorpusExporter_mock(); + $ce = new CorpusExporter(); $output_folder = $this->virtualDir->url(); $extractor_stats = array(); // this will change // $extractors is var parameter, but shouldn't change $extractors = $extractorObj->getExtractorsTable(); $expectedExtractors = $extractors; - $ce->mock_export_document($report_id,$extractors,$disamb_only,$extractor_stats,$lists,$output_folder,$subcorpora,$tagging_method); + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($ce,'export_document'); + $protectedMethod->invokeArgs($ce,array($report_id,$extractors,$disamb_only,&$extractor_stats,&$lists,$output_folder,$subcorpora,$tagging_method)); // check results in variables and files $this->assertEquals($expectedExtractors,$extractors); diff --git a/phpunit/tests/engine/include/export/CorpusExporter_part8_Test.php b/phpunit/tests/engine/include/export/CorpusExporter_part8_Test.php index 39d8b927..c43b1096 100644 --- a/phpunit/tests/engine/include/export/CorpusExporter_part8_Test.php +++ b/phpunit/tests/engine/include/export/CorpusExporter_part8_Test.php @@ -96,14 +96,15 @@ private function export_document($disamb_only,$tagging_method) global $db; $db = $dbEmu; - $ce = new CorpusExporter_mock(); $output_folder = $this->virtualDir->url(); $extractor_stats = array(); // this will change // $extractors is var parameter, but shouldn't change $extractors = $extractorObj->getExtractorsTable(); $expectedExtractors = $extractors; - $ce->mock_export_document($report_id,$extractors,$disamb_only,$extractor_stats,$lists,$output_folder,$subcorpora,$tagging_method); + $ce = new CorpusExporter(); + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($ce,'export_document'); + $protectedMethod->invokeArgs($ce,array($report_id,$extractors,$disamb_only,&$extractor_stats,&$lists,$output_folder,$subcorpora,$tagging_method)); // check results in variables and files $this->assertEquals($expectedExtractors,$extractors); diff --git a/phpunit/tests/engine/include/export/CorpusExporter_part_Test.php b/phpunit/tests/engine/include/export/CorpusExporter_part_Test.php index 9a49e583..c47613ed 100644 --- a/phpunit/tests/engine/include/export/CorpusExporter_part_Test.php +++ b/phpunit/tests/engine/include/export/CorpusExporter_part_Test.php @@ -2,9 +2,8 @@ use org\bovigo\vfs\vfsStream; // for vfsStream mb_internal_encoding("UTF-8"); -require_once("CorpusExporterTest.php"); -class CorpusExporter_part_Test extends CorpusExporterTest { +class CorpusExporter_part_Test extends PHPUnit_Framework_TestCase { private $virtualDir = null; @@ -25,7 +24,7 @@ public function test_export_document() $lists = array(); $subcorpora = array(); //String tagging method from ['tagger', 'final', 'final_or_tagger', 'user:{id}'] - $tagging_method = ''; + $tagging_method = 'tagger'; $dbEmu = new DatabaseEmulator(); @@ -87,18 +86,25 @@ public function test_export_document() 'SELECT * FROM reports WHERE id = ?', $allReturnedDataRows ); - $emptyDataRows = array(); + $emptyCorpora = array( 'ext'=>NULL ); // must have 'ext' field $dbEmu->setResponse("fetch_rows", 'SELECT * FROM corpora WHERE id = ?', - $emptyDataRows ); + array($emptyCorpora) + ); + $formatName = 'xml'; // for format_id=1 + $dbEmu->setResponse("fetch_one", + 'SELECT format FROM reports_formats WHERE id = ?', + $formatName // fetch_one - only string without array packing + ); global $db; $db = $dbEmu; - $ce = new CorpusExporter_mock(); + $ce = new CorpusExporter(); // $extractors is var parameter, but shouldn't change $expectedExtractors = $extractors; - $ce->mock_export_document($report_id,$extractors,$disamb_only,$extractor_stats,$lists,$this->virtualDir->url(),$subcorpora,$tagging_method); + $protectedMethod = TestAccessTools::createAccessToProtectedMethodOfClassObject($ce,'export_document'); + $protectedMethod->invokeArgs($ce,array($report_id,$extractors,$disamb_only,&$extractor_stats,&$lists,$this->virtualDir->url(),$subcorpora,$tagging_method)); // check results in variables and files $this->assertEquals($expectedExtractors,$extractors); $expectedLists = array(); @@ -112,7 +118,7 @@ public function test_export_document() $expectedIniContent = "[document]\nid = 1\ndate = 2022-12-16\ntitle = tytuł\nsource = source\nauthor = author\ntokenization = tokenization\nsubcorpus = "; $resultIniFile = file_get_contents($expectedBaseFileName.'.ini'); $this->assertEquals($expectedIniContent,$resultIniFile); - $expectedJsonContent = "{\n \"chunks\": [\n [\n [\n {\n \"order_id\": 0,\n \"token_id\": 0,\n \"orth\": \"e\",\n \"ctag\": null,\n \"from\": 1,\n \"to\": 1,\n \"annotations\": [],\n \"relations\": []\n }\n ]\n ]\n ],\n \"relations\": [],\n \"annotations\": []\n}"; + $expectedJsonContent = "{\n \"chunks\": [\n [\n [\n {\n \"order_id\": 0,\n \"token_id\": 0,\n \"orth\": \"e\",\n \"ctag\": \"\",\n \"from\": 1,\n \"to\": 1,\n \"annotations\": [],\n \"relations\": []\n }\n ]\n ]\n ],\n \"relations\": [],\n \"annotations\": []\n}"; $resultJsonFile = file_get_contents($expectedBaseFileName.'.json'); $this->assertEquals($expectedJsonContent,$resultJsonFile); $expectedTxtContent = $content; @@ -121,7 +127,7 @@ public function test_export_document() $expectedRelxmlContent = "\n\n\n\n"; $resultRelxmlFile = file_get_contents($expectedBaseFileName.'.rel.xml'); $this->assertEquals($expectedRelxmlContent,$resultRelxmlFile); - $expectedXmlContent = "\n\n\n \n \n \n e\n \n \n \n \n\n"; + $expectedXmlContent = "\n\n\n \n \n \n e\n \n \n \n \n\n"; $resultXmlFile = file_get_contents($expectedBaseFileName.'.xml'); $this->assertEquals($expectedXmlContent,$resultXmlFile); diff --git a/phpunit/tests/engine/include/export/FileWriterTest.php b/phpunit/tests/engine/include/export/FileWriterTest.php new file mode 100644 index 00000000..ce48b076 --- /dev/null +++ b/phpunit/tests/engine/include/export/FileWriterTest.php @@ -0,0 +1,43 @@ +virtualDir = org\bovigo\vfs\vfsStream::setup('root',null,[]); + + } // setUp() + + public function test_writeTextToFile() { + + $fileName = $this->virtualDir->url()."/test.txt"; + $text = "jnduie773nd n"; + $fw = new FileWriter(); + $fw->writeTextToFile($fileName,$text); + $result = file_get_contents($fileName); + $this->assertEquals($text,$result); + + } // test_writeTextToFile() + + public function test_writeJSONToFile() { + + $fileName = $this->virtualDir->url()."/test.txt"; + $jsonArray = array('a' => 1); + $fw = new FileWriter(); + $fw->writeJSONToFile($fileName,$jsonArray); + $result = file_get_contents($fileName); + $expected = +'{ + "a": 1 +}'; + $this->assertEquals($expected,$result); + + } // test_writeJSONToFile + +} // FileWriterTest class + +?> diff --git a/phpunit/tests/engine/include/export/XmlFactoryTest.php b/phpunit/tests/engine/include/export/XmlFactoryTest.php new file mode 100644 index 00000000..6053c6f4 --- /dev/null +++ b/phpunit/tests/engine/include/export/XmlFactoryTest.php @@ -0,0 +1,43 @@ +xmlFactory = new XmlFactory(); + + } // setUp() + +// public function exportToXmlAndRelxml($filePathWithoutExt,&$ccl,&$annotations,&$relations,&$lemmas,&$attributes) + + public function testExporttoxmlandrelxmlCallSetdatatoexportMethod() { + + $filePathWithoutExt = ''; + $annotations = array('anotacje'); + $relations = array('relacje'); + $lemmas = array('lematy'); + $attributes = array('atrybuty'); + + $mockCcl = $this->getMockBuilder(CclExportDocument::class) + -> disableArgumentCloning() + -> disableOriginalConstructor() + -> setMethods(array('setCclProperties')) + -> getMock(); + // call setCclProperties with params + $mockCcl -> expects($this->once()) + ->method('setCclProperties') + ->with($annotations,$relations,$lemmas,$attributes); + // returns modified $ccl by reference + + $this->xmlFactory->exportToXmlAndRelxml($filePathWithoutExt,$mockCcl,$annotations,$relations,$lemmas,$attributes); + + } // testExporttoxmlandrelxmlCallSetdatatoexportMethod() + +} // XmlFactoryTest class + +?> diff --git a/phpunit/tests/engine/include/structs/CclDocumentTest.php b/phpunit/tests/engine/include/structs/CclDocumentTest.php new file mode 100644 index 00000000..d589b549 --- /dev/null +++ b/phpunit/tests/engine/include/structs/CclDocumentTest.php @@ -0,0 +1,418 @@ +setFrom($from); $t->setTo($to); + $d = new CclDocument(); + $d->addToken($t); + + // on empty document token index starts from 0 + $expectedTokenIndex = 0; + // first token in token list is $t + $this->assertEquals($t,$d->tokens[$expectedTokenIndex]); + // all token chars has same token index + for($i=$from;$i<=$to;$i++) { + $this->assertEquals($expectedTokenIndex,$d->char2token[$i]); + } + + } // test_addToken_set_char2token_array() + +/* +function setAnnotationProperty($annotation_property){ +*/ + public function test_setAnnotationProperty_setInternalErrorOnNull() { + + $annotation_property = null; + + $cclDocument = new CclDocument(); + $cclDocument->setAnnotationProperty($annotation_property); + + // error message + $this->assertTrue(is_array($cclDocument->errors)); + $this->assertTrue(count($cclDocument->errors)>0); + $this->assertInstanceOf('CclError',$cclDocument->errors[0]); + + } // test_setAnnotationProperty_setInternalErrorOnNull() + + public function test_setAnnotationProperty_setInternalErrorOnEmptyArray() { + + $annotation_property = array("from"=>null); + + $cclDocument = new CclDocument(); + $cclDocument->setAnnotationProperty($annotation_property); + + // error message + $this->assertTrue(is_array($cclDocument->errors)); + $this->assertTrue(count($cclDocument->errors)>0); + $this->assertInstanceOf('CclError',$cclDocument->errors[0]); + + } // test_setAnnotationProperty_setInternalErrorOnEmptyArray() + + public function test_setAnnotationProperty() { + + $type = 1; + $from = 1; $to = 3; + $name = 'nazwa własności'; + $value = 'wartość własności'; + $annotation_property = array( + "type" => $type, + "from" => $from, + "to" => $to, + "name" => $name, + "value" => $value + ); + + // document must have valid cclToken for $from to $to chars + $t = new CclToken(); + $t->setFrom($from); $t->setTo($to); + $cclDocument = new CclDocument(); + // must set token to document to add property for this range + $cclDocument->addToken($t); + $cclDocument->setAnnotationProperty($annotation_property); + + // no error message + $this->assertTrue(is_array($cclDocument->errors)); + $this->assertEquals(count($cclDocument->errors),0); + // added property should be written to token prop table + $expectedPropTable = array( + $type.':'.$name => $value + ); + $this->assertEquals($expectedPropTable,$cclDocument->tokens[0]->prop); + + } // test_setAnnotationProperty_setInternalErrorOnEmptyArray() + +// function setAnnotationLemma($annotation_lemma){...} + + public function testAddLemmaWithNullParameterSetsError() { + + $annotation_lemma = null; + $ccl = new CclDocument(); + $ccl->setAnnotationLemma($annotation_lemma); + $this->assertEquals(1,count($ccl->errors)); // is sth in errors table + $this->assertInstanceOf('CclError',$ccl->errors[0]); // is this object + // verify message content + $expectedErrorMsg = array("Annotation out of range (annotation.from > document.char_count)"); + $this->assertEquals($expectedErrorMsg,$ccl->errors[0]->comments); + + } // testAddLemmaWithNullParameterSetsError() + + public function testAddLemmaWithEmptyParameterSetsError() { + + $annotation_lemma = array('from'=>null); // should have 'from' and 'to' field + $ccl = new CclDocument(); + $ccl->setAnnotationLemma($annotation_lemma); + $this->assertEquals(1,count($ccl->errors)); // is sth in errors table + $this->assertInstanceOf('CclError',$ccl->errors[0]); // is this object + // verify message content + $expectedErrorMsg = array("Annotation out of range (annotation.from > document.char_count)"); + $this->assertEquals($expectedErrorMsg,$ccl->errors[0]->comments); + + } // testAddLemmaWithEmptyParameterSetsError() + + public function testLemmaWithoutFromSetsError() { + + $from = 1; $to = 3; + $annotation_lemma = array('to'=>$to,'type'=>'TYP', 'from'=>null); + + $mockToken = $this->getMockBuilder(CclToken::class) + -> setMethods(['setAnnotationLemma']) -> getMock(); + // $token->setAnnotationLemma will not be called in this case + $mockToken->expects($this->never())->method('setAnnotationLemma'); + // this methods are originally, sets token range + $mockToken->setFrom($from); $mockToken->setTo($to); + + $ccl = new CclDocument(); + $ccl->addToken($mockToken); + $ccl->setAnnotationLemma($annotation_lemma); + $this->assertEquals(1,count($ccl->errors)); // is sth in errors table + $this->assertInstanceOf('CclError',$ccl->errors[0]); // is this object + // verify message content + $expectedErrorMsg = array("Annotation out of range (annotation.from > document.char_count)"); + $this->assertEquals($expectedErrorMsg,$ccl->errors[0]->comments); + + } // testLemmaWithoutFromSetsError() + + public function testLemmaWithoutFromMatchesAnyTokenSetsError() { + + $from = 1; $to = 3; + $annotation_lemma = array('from'=>$from-1,'to'=>$to,'type'=>'TYP'); + + $mockToken = $this->getMockBuilder(CclToken::class) + -> setMethods(['setAnnotationLemma']) + -> getMock(); + // $token->setAnnotationLemma will not be called in this case + $mockToken->expects($this->never())->method('setAnnotationLemma'); + // this methods are originally, sets token range + $mockToken->setFrom($from); $mockToken->setTo($to); + + $ccl = new CclDocument(); + $ccl->addToken($mockToken); + $ccl->setAnnotationLemma($annotation_lemma); + $this->assertEquals(1,count($ccl->errors)); // is sth in errors table + $this->assertInstanceOf('CclError',$ccl->errors[0]); // is this object + // verify message content + $expectedErrorMsg = array("Annotation out of range (annotation.from > document.char_count)"); + $this->assertEquals($expectedErrorMsg,$ccl->errors[0]->comments); + + } // testLemmaWithoutFromMatchesAnyTokenSetsError() + + public function testLemmaWithoutToSetsError() { + + $from = 1; $to = 3; + $annotation_lemma = array('from'=>$from,'type'=>'TYP', 'to'=>null); + + $mockToken = $this->getMockBuilder(CclToken::class) + -> setMethods(['setAnnotationLemma']) + -> getMock(); + // $token->setAnnotationLemma will not be called in this case + $mockToken->expects($this->never())->method('setAnnotationLemma'); + // this methods are originally, sets token range + $mockToken->setFrom($from); $mockToken->setTo($to); + + $ccl = new CclDocument(); + $ccl->addToken($mockToken); + $ccl->setAnnotationLemma($annotation_lemma); + $this->assertEquals(1,count($ccl->errors)); // is sth in errors table + $this->assertInstanceOf('CclError',$ccl->errors[0]); // is this object + // verify message content + $expectedErrorMsg = array("Annotation out of range (annotation.to > document.char_count)"); + $this->assertEquals($expectedErrorMsg,$ccl->errors[0]->comments); + + } // testLemmaWithoutToSetsError + + public function testLemmaWithoutToMatchesAnyTokenSetsError() { + + $from = 1; $to = 3; + $annotation_lemma = array('from'=>$from,'to'=>$to+1,'type'=>'TYP'); + + $mockToken = $this->getMockBuilder(CclToken::class) + -> setMethods(['setAnnotationLemma']) + -> getMock(); + // $token->setAnnotationLemma will not be called in this case + $mockToken->expects($this->never())->method('setAnnotationLemma'); + // this methods are originally, sets token range + $mockToken->setFrom($from); $mockToken->setTo($to); + + $ccl = new CclDocument(); + $ccl->addToken($mockToken); + $ccl->setAnnotationLemma($annotation_lemma); + $this->assertEquals(1,count($ccl->errors)); // is sth in errors table + $this->assertInstanceOf('CclError',$ccl->errors[0]); // is this object + // verify message content + $expectedErrorMsg = array("Annotation out of range (annotation.to > document.char_count)"); + $this->assertEquals($expectedErrorMsg,$ccl->errors[0]->comments); + + } // testLemmaWithoutToMatchesAnyTokenSetsError() + + public function testLemmaWithoutTypeCallTokenSetLemmaMethodProperly() { + + $from = 1; $to = 3; + $annotation_lemma = array('from'=>$from,'to'=>$to); + + $mockToken = $this->getMockBuilder(CclToken::class) + -> setMethods(['setAnnotationLemma']) + -> getMock(); + // $token->setAnnotationLemma will be called exactly once + $mockToken->expects($this->once())->will($this->returnValue(True))->method('setAnnotationLemma'); + // this methods are originally, sets token range + $mockToken->setFrom($from); $mockToken->setTo($to); + + $ccl = new CclDocument(); + $ccl->addToken($mockToken); + $ccl->setAnnotationLemma($annotation_lemma); + $this->assertEquals(0,count($ccl->errors)); // no errors + + } // testLemmaWithoutTypeCallTokenSetLemmaMethodProperly() + + public function testSetAnnotationLemmaCallTokenSetLemmaMethod() { + + $from = 1; $to = 3; + $annotation_lemma = array('from'=>$from,'to'=>$to,'type'=>'TYP'); + + $mockToken = $this->getMockBuilder(CclToken::class) + -> setMethods(['setAnnotationLemma']) + -> getMock(); + // $token->setAnnotationLemma will be called exactly once + $mockToken->expects($this->once())->will($this->returnValue(True))->method('setAnnotationLemma'); + // this methods are originally, sets token range + $mockToken->setFrom($from); $mockToken->setTo($to); + + $ccl = new CclDocument(); + $ccl->addToken($mockToken); + $ccl->setAnnotationLemma($annotation_lemma); + $this->assertEquals(0,count($ccl->errors)); // no errors + + } // testSetAnnotationLemmaCallTokenSetLemmaMethod() + + public function testTokenSetLemmaReturnFalseSetsError() { + + $from = 1; $to = 3; + $annotation_lemma = array('from'=>$from,'to'=>$to,'type'=>'TYP'); + + $mockToken = $this->getMockBuilder(CclToken::class) + -> setMethods(['setAnnotationLemma']) + -> getMock(); + // $token->setAnnotationLemma will be called exactly once + $mockToken->expects($this->once())->will($this->returnValue(False))->method('setAnnotationLemma'); + // this methods are originally, sets token range + $mockToken->setFrom($from); $mockToken->setTo($to); + + $ccl = new CclDocument(); + $ccl->addToken($mockToken); + $ccl->setAnnotationLemma($annotation_lemma); + $this->assertEquals(1,count($ccl->errors)); // is sth in errors table + $this->assertInstanceOf('CclError',$ccl->errors[0]); // is this object + // verify message content + $expectedErrorMsg = array("000 cannot set annotation lemma to specific token"); + $this->assertEquals($expectedErrorMsg,$ccl->errors[0]->comments); + + } // testTokenSetLemmaReturnFalseSetsError() + + public function testLemmaOverMultiTokensCallSetLemmaForFirstOneOnly() { + + $from = 1; $to = 5; + $annotation_lemma = array('from'=>$from,'to'=>$to,'type'=>'TYP'); + + $mockToken1 = $this->getMockBuilder(CclToken::class) + -> setMethods(['setAnnotationLemma']) + -> getMock(); + // $token->setAnnotationLemma this should will be called exactly once + $mockToken1->expects($this->once())->will($this->returnValue(True))->method('setAnnotationLemma'); + $mockToken1->setFrom($from); $mockToken1->setTo(3); + $mockToken2 = $this->getMockBuilder(CclToken::class) + -> setMethods(['setAnnotationLemma']) + -> getMock(); + // $token->setAnnotationLemma this shouldn't never be called + $mockToken2->expects($this->never())->method('setAnnotationLemma'); + $mockToken2->setFrom(4); $mockToken2->setTo($to); + + $ccl = new CclDocument(); + $ccl->addToken($mockToken1); $ccl->addToken($mockToken2); + $ccl->setAnnotationLemma($annotation_lemma); + $this->assertEquals(0,count($ccl->errors)); // no errors + + } // testLemmaOverMultiTokensCallSetLemmaForFirstOneOnly() + +// function setAnnotation($annotation) + + private function generateProperCclToSetAnnotationTests($from,$to) { + + // token on chars from $from to $to + $token = new cclToken(); + $token->setFrom($from); $token->setTo($to); + // add token to tree structure + $sentence = new CclSentence(); + $sentence->addToken($token); + $chunk = new CclChunk(); + $chunk->addSentence($sentence); + $ccl = new CclDocument(); + // set token to $ccl->tokens at pos. 0 + // and fill 3 first places at char2token to this index + $ccl->addToken($token); + // set chunk->sentence->token object tree also + $ccl->addChunk($chunk); + + return $ccl; + + } // generateProperCclToSetAnnotationTests + + public function testSetannotationWithNullParameterSetsError() { + + $annotation = null; + // must be token in $ccl + $ccl = $this->generateProperCclToSetAnnotationTests(1,3); + + $ccl->setAnnotation($annotation); + + $this->assertEquals(1,count($ccl->errors)); // is sth in errors table + $this->assertInstanceOf('CclError',$ccl->errors[0]); // is this object + $expectedErrorMsg = array("Annotation out of range (annotation.from > document.char_count)"); + $this->assertEquals($expectedErrorMsg,$ccl->errors[0]->comments); + + } // testSetannotationWithNullParameterSetsError() + + public function testSetannotationWithAnnotationWithoutFromSetsError() { + + $annotation = array('type'=>"TYP", 'to'=>3, 'value'=>'VALUE', 'name'=>'NAME', 'from'=>null ); + // must be token in $ccl + $ccl = $this->generateProperCclToSetAnnotationTests(1,3); + + $ccl->setAnnotation($annotation); + $this->assertEquals(1,count($ccl->errors)); // is sth in errors table + $this->assertInstanceOf('CclError',$ccl->errors[0]); // is this object + $expectedErrorMsg = array("Annotation out of range (annotation.from > document.char_count)"); + $this->assertEquals($expectedErrorMsg,$ccl->errors[0]->comments); + + } // testSetannotationWithEmptyAnnotationSetsError() + + public function testSetannotationForProperDataCallsTokensSetannotation() { + + $from = 1; $to = 3; + $annotation = array( 'type'=>"TYP", 'from'=>1, 'to'=>3, 'value'=>'VALUE', 'name'=>'NAME' ); + + $mockToken = $this->getMockBuilder(CclToken::class) + -> setMethods(['setAnnotation']) + -> getMock(); + // $token->setAnnotation will be called exactly once returns True + $mockToken->expects($this->once())->will($this->returnValue(True))->method('setAnnotation'); + // this methods are originally, sets token range + $mockToken->setFrom($from); $mockToken->setTo($to); + $mockSentence = $this->getMockBuilder(CclSentence::class) + -> setMethods(['incChannel','fillChannel']) + -> getMock(); + // incChannel() should be called once on argument $annotation['type'] + $mockSentence->expects($this->once())->method('incChannel')->with($annotation['type']); + // fillChannel() should be called once on argument $annotation['type'] + $mockSentence->expects($this->once())->method('fillChannel')->with($annotation['type']); + $mockSentence->channels = array(); + $mockDocument = $this->getMockBuilder(CclDocument::class) + -> setMethods(['getSentenceByToken']) + -> getMock(); + $mockDocument->expects($this->exactly(2))->will($this->returnValue($mockSentence))->method('getSentenceByToken'); + $mockDocument->addToken($mockToken); + + $expectedTokenProp = array( + "sense:".$annotation["type"]=>$annotation['value'] + ); + $mockDocument->setAnnotation($annotation); + $this->assertEquals(0,count($mockDocument->errors)); // no errors + // annotation.value is direct set to prop table in token + $this->assertEquals($expectedTokenProp,$mockToken->prop); + // in token in main ccl table + $this->assertEquals($expectedTokenProp,$mockDocument->tokens[0]->prop); + //var_dump($mockDocument->chunks); + + } // testSetannotationForProperDataCallsTokensSetannotation() + + public function testSetannotationForProperDataSetPropInTokenAndTypeInChannels() { + + $from = 1; $to = 3; + $annotation = array( 'type'=>"TYP", 'from'=>1, 'to'=>3, 'value'=>'VALUE', 'name'=>'NAME', 'id'=>'ID' ); + // must be token in proper range in $ccl + $ccl = $this->generateProperCclToSetAnnotationTests($from,$to); + + $ccl->setAnnotation($annotation); + + $this->assertEquals(0,count($ccl->errors)); // no errors + // annotation.value is direct set to prop table in token + $expectedTokenProp = array( + "sense:".$annotation["type"]=>$annotation['value'] + ); + // in token in main ccl table + $this->assertEquals($expectedTokenProp,$ccl->tokens[0]->prop); + // and in chunks->sentence->tokens tree + $this->assertEquals($expectedTokenProp,$ccl->chunks[0]->sentences[0]->tokens[0]->prop); + // set channel in sentence + $expectedSentenceChannels = array( $annotation["type"]=>1 ); + $this->assertEquals($expectedSentenceChannels,$ccl->chunks[0]->sentences[0]->channels); + + } // testSetannotationForProperDataSetPropInTokenAndTypeInChannels() + +} // CclDocumentTest class diff --git a/phpunit/tests/engine/include/structs/CclStruct_CclDocumentTest.php b/phpunit/tests/engine/include/structs/CclStruct_CclDocumentTest.php deleted file mode 100644 index f4a568d1..00000000 --- a/phpunit/tests/engine/include/structs/CclStruct_CclDocumentTest.php +++ /dev/null @@ -1,93 +0,0 @@ -setFrom($from); $t->setTo($to); - $d = new CclDocument(); - $d->addToken($t); - - // on empty document token index starts from 0 - $expectedTokenIndex = 0; - // first token in token list is $t - $this->assertEquals($t,$d->tokens[$expectedTokenIndex]); - // all token chars has same token index - for($i=$from;$i<=$to;$i++) { - $this->assertEquals($expectedTokenIndex,$d->char2token[$i]); - } - - } // test_addToken_set_char2token_array() - -/* -function setAnnotationProperty($annotation_property){ -*/ - public function test_setAnnotationProperty_setInternalErrorOnNull() { - - $annotation_property = null; - - $cclDocument = new CclDocument(); - $cclDocument->setAnnotationProperty($annotation_property); - - // error message - $this->assertTrue(is_array($cclDocument->errors)); - $this->assertTrue(count($cclDocument->errors)>0); - $this->assertInstanceOf('CclError',$cclDocument->errors[0]); - - } // test_setAnnotationProperty_setInternalErrorOnNull() - - public function test_setAnnotationProperty_setInternalErrorOnEmptyArray() { - - $annotation_property = array(); - - $cclDocument = new CclDocument(); - $cclDocument->setAnnotationProperty($annotation_property); - - // error message - $this->assertTrue(is_array($cclDocument->errors)); - $this->assertTrue(count($cclDocument->errors)>0); - $this->assertInstanceOf('CclError',$cclDocument->errors[0]); - - } // test_setAnnotationProperty_setInternalErrorOnEmptyArray() - - public function test_setAnnotationProperty() { - - $type = 1; - $from = 1; $to = 3; - $name = 'nazwa własności'; - $value = 'wartość własności'; - $annotation_property = array( - "type" => $type, - "from" => $from, - "to" => $to, - "name" => $name, - "value" => $value - ); - - // document must have valid cclToken for $from to $to chars - $t = new CclToken(); - $t->setFrom($from); $t->setTo($to); - $cclDocument = new CclDocument(); - // must set token to document to add property for this range - $cclDocument->addToken($t); - $cclDocument->setAnnotationProperty($annotation_property); - - // no error message - $this->assertTrue(is_array($cclDocument->errors)); - $this->assertEquals(count($cclDocument->errors),0); - // added property should be written to token prop table - $expectedPropTable = array( - $type.':'.$name => $value - ); - $this->assertEquals($expectedPropTable,$cclDocument->tokens[0]->prop); - - } // test_setAnnotationProperty_setInternalErrorOnEmptyArray() - - - -} // class diff --git a/phpunit/tests/engine/include/structs/CclStruct_CclTokenTest.php b/phpunit/tests/engine/include/structs/CclStruct_CclTokenTest.php deleted file mode 100644 index 9602aea1..00000000 --- a/phpunit/tests/engine/include/structs/CclStruct_CclTokenTest.php +++ /dev/null @@ -1,65 +0,0 @@ -assertInstanceOf('CclToken',new CclToken()); - } // test_createObjectOfCclTokenClass() - - public function test_From_GetWhatWasSet() { - - $from = 1; - $t = new CclToken(); - $t->setFrom($from); - $result = $t->getFrom(); - $expectedFrom = $from; // what was set is what we get - $this->assertEquals($expectedFrom,$result); - - } // test_From_GetWhatWasSet() - - public function test_To_GetWhatWasSet() { - - $to = 1; - $t = new CclToken(); - $t->setTo($to); - $result = $t->getTo(); - $expectedTo = $to; // what was set is what we get - $this->assertEquals($expectedTo,$result); - - } // test_To_GetWhatWasSet() - - public function test_setAnnotationProperty() { - - $type = 1; // ID - $name = 'nazwa'; // string - $value = 'wartość'; - // for this function $annotation_property must have - // minimal fields: 'type', 'name', 'value' - $annotation_property = array( - "type" => $type, - "name" => $name, - "value" => $value - ); - - // do test - $t = new CclToken(); // $t->prop is null here - $result = $t->setAnnotationProperty($annotation_property); - - // setAnnotationProperty returns always True - $this->assertTrue($result); - // there are no method to get setting property, we must examine - // internal table prop[] - $this->assertTrue(is_array($t->prop)); - $expectedNumerOfProperties = 1; - $this->assertEquals($expectedNumerOfProperties,count($t->prop)); - $expectedPropTable = array( - $type.':'.$name => $value - ); - $this->assertEquals($expectedPropTable,$t->prop); - - } - -} // class diff --git a/phpunit/tests/engine/include/structs/CclTokenTest.php b/phpunit/tests/engine/include/structs/CclTokenTest.php new file mode 100644 index 00000000..b58288c1 --- /dev/null +++ b/phpunit/tests/engine/include/structs/CclTokenTest.php @@ -0,0 +1,287 @@ +assertInstanceOf('CclToken',new CclToken()); + } // test_createObjectOfCclTokenClass() + + public function test_From_GetWhatWasSet() { + + $from = 1; + $t = new CclToken(); + $t->setFrom($from); + $result = $t->getFrom(); + $expectedFrom = $from; // what was set is what we get + $this->assertEquals($expectedFrom,$result); + + } // test_From_GetWhatWasSet() + + public function test_To_GetWhatWasSet() { + + $to = 1; + $t = new CclToken(); + $t->setTo($to); + $result = $t->getTo(); + $expectedTo = $to; // what was set is what we get + $this->assertEquals($expectedTo,$result); + + } // test_To_GetWhatWasSet() + + public function test_setAnnotationProperty() { + + $type = 1; // ID + $name = 'nazwa'; // string + $value = 'wartość'; + // for this function $annotation_property must have + // minimal fields: 'type', 'name', 'value' + $annotation_property = array( + "type" => $type, + "name" => $name, + "value" => $value + ); + + // do test + $t = new CclToken(); // $t->prop is null here + $result = $t->setAnnotationProperty($annotation_property); + + // setAnnotationProperty returns always True + $this->assertTrue($result); + // there are no method to get setting property, we must examine + // internal table prop[] + $this->assertTrue(is_array($t->prop)); + $expectedNumerOfProperties = 1; + $this->assertEquals($expectedNumerOfProperties,count($t->prop)); + $expectedPropTable = array( + $type.':'.$name => $value + ); + $this->assertEquals($expectedPropTable,$t->prop); + + } + +// function setAnnotationLemma($annotation_lemma){...} + + public function testNullLemmaSetsPropForLemmaSuffixToNull() { + + $annotation_lemma = null; + + $token = new CclToken(); + $result = $token->setAnnotationLemma($annotation_lemma); + + $this->assertTrue($result); // always returns True + $expectedPropKey = ":lemma"; + $this->assertNull($token->prop[$expectedPropKey]); + + } // testEmptyLemmaSetsPropForLemmaSuffixToNull() + + public function testEmptyLemmaSetsPropForLemmaSuffixToNull() { + + $annotation_lemma = array("type"=>null, "lemma"=>null); + + $token = new CclToken(); + $result = $token->setAnnotationLemma($annotation_lemma); + + $this->assertTrue($result); // always returns True + $expectedPropKey = ":lemma"; + $this->assertNull($token->prop[$expectedPropKey]); + + } // testEmptyLemmaSetsPropForLemmaSuffixToNull() + + public function testLemmaWithoutTypeSetsPropForLemmaSuffix() { + + $lemmaText = "LEMMA"; + $annotation_lemma = array( 'lemma'=>$lemmaText, "type"=>null ); + + $token = new CclToken(); + $result = $token->setAnnotationLemma($annotation_lemma); + + $this->assertTrue($result); // always returns True + $expectedPropKey = ":lemma"; + $expectedLemma = $lemmaText; + $this->assertEquals($expectedLemma,$token->prop[$expectedPropKey]); + + } // testLemmaWithoutTypeSetsPropForLemmaSuffix() + + public function testLemmaWithoutLemmaTextSetsPropWithLemmaToNull() { + + $lemmaType = "TYP"; + $annotation_lemma = array( 'type'=>$lemmaType, "lemma"=>null ); + + $token = new CclToken(); + $result = $token->setAnnotationLemma($annotation_lemma); + + $this->assertTrue($result); // always returns True + $expectedPropKey = $lemmaType.":lemma"; + $this->assertNull($token->prop[$expectedPropKey]); + + } // testLemmaWithoutLemmaTextSetsPropWithLemmaToNull() + + public function testSetAnnotationLemmaSetsPropWithLemmaSuffix() { + + $lemmaType = "TYP"; $lemmaText = "LEMMA"; + $annotation_lemma = array( 'type'=>$lemmaType, 'lemma'=>$lemmaText ); + + $token = new CclToken(); + $result = $token->setAnnotationLemma($annotation_lemma); + + $this->assertTrue($result); // always returns True + $expectedPropKey = $lemmaType.":lemma"; + $expectedLemma = $lemmaText; + $this->assertEquals($expectedLemma,$token->prop[$expectedPropKey]); + + } // testSetAnnotationLemmaSetsPropWithLemmaSuffix() + +// function setAnnotation($annotation,$parentChannels = null) + + public function testSetannotationWithoutTypeFieldWorksAsNonSense() { + + $id=10; + $annotation = array( 'id'=>$id, 'value'=>array(1,2,3), "type"=>null ); + $parentChannels = null; + + $token = new CclToken(); + $result = $token->setAnnotation($annotation,$parentChannels); + // should return True + $this->assertTrue($result); + // in tabel token.channels key "" should be used if type not exist + $expectedTypeChannel = $id; + $this->assertEquals($expectedTypeChannel,$token->channels[""]); + // for other types than 'sense' there are not prop attribute + $this->assertNull($token->prop); + + } // testSetannotationWithoutTypeFieldWorksAsNonSense() + + public function testSetannotationIfChannelForTypeExistsPreserveExistingAndReturnsFalse() { + + $type = 'TYP'; $id=10; $existingIdForChannel = 17; + $annotation = array('type'=>$type, 'id'=>$id, 'value'=>array(1,2,3)); + $parentChannels = null; + + $token = new CclToken(); + $token->channels[$type] = $existingIdForChannel; + $result = $token->setAnnotation($annotation,$parentChannels); + // should return False in this case + $this->assertFalse($result); + // in tabel token.channels should be [$type]=>$annotation.id + $expectedTypeChannel = $existingIdForChannel; // preserve existing + $this->assertEquals($expectedTypeChannel,$token->channels[$type]); + // for other types than 'sense' there are not prop attribute + $this->assertNull($token->prop); + + } // testSetannotationIfChannelForTypeExistsPreserveExistingAndReturnsFalse() + + public function testParentChannelsWithoutTypeKeyBlocksAdding() { + + $type = 'TYP'; $id=10; + $annotation = array('type'=>$type, 'id'=>$id, 'value'=>array(1,2,3)); + $parentChannels = array( ); + + $token = new CclToken(); + $result = $token->setAnnotation($annotation,$parentChannels); + // should return False if parent channels for type doesn't exists + $this->assertFalse($result); + // table token.channels remains empty + $this->assertEquals(array(),$token->channels); + // for other types than 'sense' there are not prop attribute + $this->assertNull($token->prop); + + } // testParentChannelsWithoutTypeKeyBlocksAdding() + + public function testParentChannelsWithTypeKeyAddsAnnotationLocally() { + + $type = 'TYP'; $id=10; + $annotation = array('type'=>$type, 'id'=>$id, 'value'=>array(1,2,3)); + $parentChannels = array( $type=>0 ); + + $token = new CclToken(); + $result = $token->setAnnotation($annotation,$parentChannels); + // should return True if add locally + $this->assertTrue($result); + // in tabel token.channels should be [$type]=>$annotation.id + $expectedTypeChannel = $id; + $this->assertEquals($expectedTypeChannel,$token->channels[$type]); + // for other types than 'sense' there are not prop attribute + $this->assertNull($token->prop); + + } // testParentChannelsWithTypeKeyAddsAnnotationLocally() + + public function testSenseTypeWhenExistsValueWithSameCountReturnsFalse() { + + $type = 'sense'; $id=10; + $annotation = array('type'=>$type, 'id'=>$id, 'value'=>array(1,2,3)); + $parentChannels = null; + $existingProp = array(1,1,1); // 3 times as in 'value' + + $token = new CclToken(); + $token->prop = $existingProp; + $result = $token->setAnnotation($annotation,$parentChannels); + // should returs False for this case + $this->assertFalse($result); + // table token.channels remains empty + $this->assertEquals(array(),$token->channels); + // token.prop remains as was + $this->assertEquals($existingProp,$token->prop); + + } // testSenseTypeWhenExistsValueWithSameCountReturnsFalse() + + public function testSenseTypeWhenExistsValueWithLessCountReplaceProp() { + + $type = 'sense'; $id=10; + $annotation = array('type'=>$type, 'id'=>$id, 'value'=>array(1,2,3)); + $parentChannels = null; + $existingProp = array(1,1); // 2 times less as in 'value' + + $token = new CclToken(); + $token->prop = $existingProp; + $result = $token->setAnnotation($annotation,$parentChannels); + // should return True + $this->assertTrue($result); + // in tabel token.channels should be [$type]=>$annotation.id + $expectedTypeChannel = $id; + $this->assertEquals($expectedTypeChannel,$token->channels[$type]); + // for 'sense' type prop is set to value + $this->assertEquals($annotation['value'],$token->prop); + + } // testSenseTypeWhenExistsValueWithLessCountReplaceProp() + + + public function testSetannotationWithFullDataSetsChannels() { + + $type = 'TYP'; $id=10; + $annotation = array('type'=>$type, 'id'=>$id, 'value'=>array(1,2,3)); + $parentChannels = null; + + $token = new CclToken(); + $result = $token->setAnnotation($annotation,$parentChannels); + // should return True + $this->assertTrue($result); + // in tabel token.channels should be [$type]=>$annotation.id + $expectedTypeChannel = $id; + $this->assertEquals($expectedTypeChannel,$token->channels[$type]); + // for other types than 'sense' there are not prop attribute + $this->assertNull($token->prop); + + } // testSetannotationWithFullDataSetsChannels() + + public function testSetannotationWithSenseTypeSetsPropTable() { + + $type = 'sense'; $id=10; + $annotation = array('type'=>$type, 'id'=>$id, 'value'=>array(1,2,3)); + $parentChannels = null; + + $token = new CclToken(); + $result = $token->setAnnotation($annotation,$parentChannels); + // should return True + $this->assertTrue($result); + // in tabel token.channels should be [$type]=>$annotation.id + $expectedTypeChannel = $id; + $this->assertEquals($expectedTypeChannel,$token->channels[$type]); + // for 'sense' type prop is set to value + $this->assertEquals($annotation['value'],$token->prop); + + } // testSetannotationWithSenseTypeSetsPropTable() + +} // CclTokenTest class diff --git a/phpunit/tests/engine/include/utils/CReportContentTest.php b/phpunit/tests/engine/include/utils/CReportContentTest.php index 906c2e31..3ef8c16b 100644 --- a/phpunit/tests/engine/include/utils/CReportContentTest.php +++ b/phpunit/tests/engine/include/utils/CReportContentTest.php @@ -8,7 +8,7 @@ class CReportContentTest extends PHPUnit_Framework_TestCase public function test_getHtmlStr_returnsHtmlStr2Object_onEmptyArray() { - $testReport = array(); + $testReport = array('content'=>null, 'format'=>null); $result = ReportContent::getHtmlStr($testReport); $this->assertInstanceOf('HtmlStr2',$result); @@ -16,7 +16,7 @@ public function test_getHtmlStr_returnsHtmlStr2Object_onEmptyArray() { public function test_getHtmlStr_returnsHtmlStr2Object_onArrayWoFormat() { - $testReport = array("content"=>$this->testContent); + $testReport = array("content"=>$this->testContent, 'format'=>null); $result = ReportContent::getHtmlStr($testReport); $this->assertInstanceOf('HtmlStr2',$result); diff --git a/phpunit/tests/engine/include/writers/CCclWriterTest.php b/phpunit/tests/engine/include/writers/CCclWriterTest.php new file mode 100644 index 00000000..b57258e7 --- /dev/null +++ b/phpunit/tests/engine/include/writers/CCclWriterTest.php @@ -0,0 +1,653 @@ +assertEquals($this->xml2Dom($expectedXml), + $this->xml2Dom($resultXml)); + + } // assertXmls() + + private function getXmlElement($xmlStr,$elementName){ + // return xml export DOM element + return $this->xml2Dom($xmlStr)->{$elementName}; + } // getXmlElement() + + private function getXmlAttribute($xmlElement,$attributeName){ + // return attribute of SimpleXmlElement + return $xmlElement->attributes()->{$attributeName}; + } // getXmlAttribute() + + private function getXmlElementAttribute($xmlStr,$elementName,$attributeName) { + // return xml export DOM element atributte + $element = $this->getXmlElement($xmlStr,$elementName); + $attribute = $this->getXmlAttribute($element,$attributeName); + return $attribute; + } // getXmlElementAttribute() + + private function getExpectedXmlProlog() { + + return + ''."\n". + ''."\n"; + + } // getExpectedXmlProlog() + + private function getExpectedEmptyChunkList() { + + return $this->getExpectedXmlProlog() + .''."\n".''."\n"; + + } // getExpectedEmptyChunkList() + + private function getExpectedEmptyRelationList() { + + return $this->getExpectedXmlProlog() + .''."\n".''."\n"; + + } // getExpectedEmptyRelationList() + + // mocked data for simple tests + + private function createMockLexeme($disamb,$base,$ctag){ + + $mockLexeme = $this->getMockBuilder(CclLexeme::class) + -> setMethods(['getDisamb','getBase','getCtag']) + -> getMock(); + $mockLexeme->method('getDisamb')->will($this->returnValue($disamb)); + $mockLexeme->method('getBase')->will($this->returnValue($base)); + $mockLexeme->method('getCtag')->will($this->returnValue($ctag)); + return $mockLexeme; + + } // createMockLexeme() + + private function createMockToken($orth,$ns=false,$prop=null,$lexemes=array(),$channels=array()){ + // 'from', 'to' property aren't used in XML export + $mockToken = $this->getMockBuilder(CclToken::class) + -> setMethods(['getOrth','getChannels','getLexemes']) + -> getMock(); + //$mockToken->prop = array($tokenPropKey=>$tokenPropValue); + $mockToken->prop = $prop; // should be array($key=>$val,...) + $mockToken->ns = $ns; + $mockToken->method('getOrth')->will($this->returnValue($orth)); + $mockToken->method('getChannels')->will($this->returnValue($channels)); + $mockToken->method('getLexemes')->will($this->returnValue($lexemes)); + return $mockToken; + + } // createMockToken() + + private function createMockSentence($id,$tokens=array()) { + + $mockSentence = $this->getMockBuilder(CclSentence::class) + -> setMethods(['getId','getTokens']) + -> getMock(); + $mockSentence->method('getId')->will($this->returnValue($id)); + $mockSentence->method('getTokens')->will($this->returnValue($tokens)); + return $mockSentence; + + } // createMockSentence() + + private function createMockChunk($id,$type,$sentences=array()) { + + $mockChunk = $this->getMockBuilder(CclChunk::class) + -> setMethods(['getId','getType','getSentences']) + -> getMock(); + $mockChunk->method('getId')->will($this->returnValue($id)); + $mockChunk->method('getType')->will($this->returnValue($type)); + $mockChunk->method('getSentences')->will($this->returnValue($sentences)); + return $mockChunk; + + } // createMockChunk() + + private function createMockCclRelation($name,$set,$fromSentence,$fromType,$fromChannel,$toSentence,$toType,$toChannel) { + + $mockRelation = $this->getMockBuilder(CclRelation::class) + -> setMethods(array('getName','getSet','getFromSentence', + 'getFromType','getFromChannel', + 'getToSentence','getToType','getToChannel')) + -> getMock(); + $mockRelation->method('getName')->will($this->returnValue($name)); + $mockRelation->method('getSet')->will($this->returnValue($set)); + $mockRelation->method('getFromSentence')->will($this->returnValue($fromSentence)); + $mockRelation->method('getFromType')->will($this->returnValue($fromType)); + $mockRelation->method('getFromChannel')->will($this->returnValue($fromChannel)); + $mockRelation->method('getToSentence')->will($this->returnValue($toSentence)); + $mockRelation->method('getToType')->will($this->returnValue($toType)); + $mockRelation->method('getToChannel')->will($this->returnValue($toChannel)); + return $mockRelation; + + } // createMockCclRelation() + + private function createMockCclDocument($chunks=array(),$relations=array()) { + + $mockCclDocument = $this->getMockBuilder(CclDocument::class) + // wszystkie pozostałe metody są oryginalne + -> setMethods(array('getChunks','getRelations')) + -> getMock(); + $mockCclDocument->method('getChunks')->will($this->returnValue($chunks)); + $mockCclDocument->method('getRelations')->will($this->returnValue($relations)); + return $mockCclDocument; + + } // createMockCclDocument() + + private function generateFullCclData() { + + $mockChunk = $this->createMockChunk("1","TYP",array( + $this->createMockSentence("1",array( + $this->createMockToken("To"), + $this->createMockToken("jest"), + $this->createMockToken("duże"), + $this->createMockToken("okno"), + $this->createMockToken(".",true) // true sets ns in Token + )), + $this->createMockSentence("2",array( + $this->createMockToken("Bardzo"), + $this->createMockToken("duże"), + $this->createMockToken(".",true) // true sets ns in Token + )) + )); + $relations = array( + $this->createMockCclRelation( + 'relName','relSet', + 'fromSentence','fromType','fromChannel', + 'toSentence','toType','toChannel') + ); + $ccl = $this->createMockCclDocument( + array($mockChunk), + $relations + ); + // duplicate tokens on main $ccl level + foreach($ccl->chunks as $chunk) { + foreach($chunk->sentences as $sentence) { + foreach($sentence->tokens as $token) { + $ccl->addToken($token); + } // tokens + } // sentences + } // chunks + return $ccl; + + } // generateFullCclData() + + private function generateExpectedXMLForFullCclData() { + + $expectedXml = $this->getExpectedXmlProlog() + .''."\n" + .' '."\n" + .' '."\n" + .' '."\n" + .' To'."\n" + .' '."\n" + .' '."\n" + .' jest'."\n" + .' '."\n" + .' '."\n" + .' duże'."\n" + .' '."\n" + .' '."\n" + .' okno'."\n" + .' '."\n" + .' '."\n" + .' .'."\n" + .' '."\n" + .' '."\n" + .' '."\n" + .' '."\n" + .' '."\n" + .' Bardzo'."\n" + .' '."\n" + .' '."\n" + .' duże'."\n" + .' '."\n" + .' '."\n" + .' .'."\n" + .' '."\n" + .' '."\n" + .' '."\n" + .' '."\n" + .' '."\n" + .' '."\n" + .' fromChannel'."\n" + .' toChannel'."\n" + .' '."\n" + .' '."\n" + .''."\n"; + ; + return $expectedXml; + + } // generateExpectedXMLForFullCclData() + + protected function setUp() { + + $this->virtualDir = org\bovigo\vfs\vfsStream::setup('root',null,[]); + $this->fileName = $this->virtualDir->url()."/test.txt"; + + } // setUp() + + // static function write($ccl, $filename, $mode){...} + + // private function makeXmlData($ccl,$mode) {...} + + public function testCleanCclMakesOnlyXmlSkeleton() { + + // empty $ccl data generates PHP Fatal Error + /* + $ccl = null; + $mode = CclWriter::$CCL; + CclWriter::write($ccl, $this->filename, $mode); + */ + + $ccl = new CclDocument(); + + // private method need reflection to tests + $privateMethod = new ReflectionMethod('CclWriter','makeXmlData'); + $privateMethod->setAccessible(True); + + $mode = CclWriter::$CCL; + $expectedXml = $this->getExpectedEmptyChunkList(); + $result = $privateMethod->invoke(new CclWriter(),$ccl,$mode); + $this->assertEquals($expectedXml,$result); + + $mode = CclWriter::$CCLREL; + $result = $privateMethod->invoke(new CclWriter(),$ccl,$mode); + $this->assertEquals($expectedXml,$result); + + $mode = CclWriter::$REL; + $expectedXml = $this->getExpectedEmptyRelationList(); + $result = $privateMethod->invoke(new CclWriter(),$ccl,$mode); + $this->assertEquals($expectedXml,$result); + + } // testCleanCclMakesOnlyXmlSkeleton() + + public function testCclWithEmptyChunkMakesOnlyXmlSkeletonWithAttributes() { + + $chunkId = '15'; + $chunkType = 'ChType'; + $mockChunk = $this->createMockChunk($chunkId,$chunkType); + $ccl = $this->createMockCclDocument(array($mockChunk)); + + // private method need reflection to tests + $privateMethod = new ReflectionMethod('CclWriter','makeXmlData'); + $privateMethod->setAccessible(True); + + $mode = CclWriter::$CCL; + /* + $expectedXml = $this->getExpectedXmlProlog() + .''."\n" + .' '."\n" + .' '."\n" + .''."\n"; + */ + $expectedXml = $this->getExpectedXmlProlog().''; + $result = $privateMethod->invoke(new CclWriter(),$ccl,$mode); + $this->assertXmls($expectedXml,$result); + $this->assertEquals($this->getXmlElement('','chunk'),$this->getXmlElement($result,'chunk')); + $this->assertEquals($this->getXmlElement($expectedXml,'chunk'),$this->getXmlElement($result,'chunk')); + // element is empty & has attributes properly set + $this->assertEquals('',$this->getXmlElement($result,'chunk')); + $this->assertEquals($chunkId,$this->getXmlElementAttribute($result,'chunk','id')); + $this->assertEquals($chunkType,$this->getXmlElementAttribute($result,'chunk','type')); + + $mode = CclWriter::$CCLREL; + $result = $privateMethod->invoke(new CclWriter(),$ccl,$mode); + $this->assertXmls($expectedXml,$result); + // element is empty & has attributes properly set + $this->assertEquals('',$this->getXmlElement($result,'chunk')); + $this->assertEquals($chunkId,$this->getXmlElementAttribute($result,'chunk','id')); + $this->assertEquals($chunkType,$this->getXmlElementAttribute($result,'chunk','type')); + + $mode = CclWriter::$REL; + $expectedXml = $this->getExpectedEmptyRelationList(); + $result = $privateMethod->invoke(new CclWriter(),$ccl,$mode); + $this->assertEquals($expectedXml,$result); + + } // testCclWithEmptyChunkMakesOnlyXmlSkeletonWithAttributes() + + public function testCclWithEmptySentenceMakesSentenceSkeletonWithId() { + + $chunkId = '15'; + $chunkType = 'ChType'; + $sentenceId = '234'; + $mockSentence = $this->createMockSentence($sentenceId); + $mockChunk = $this->createMockChunk($chunkId,$chunkType,array($mockSentence)); + $ccl = $this->createMockCclDocument(array($mockChunk)); + + // private method need reflection to tests + $privateMethod = new ReflectionMethod('CclWriter','makeXmlData'); + $privateMethod->setAccessible(True); + + $mode = CclWriter::$CCL; + $result = $privateMethod->invoke(new CclWriter(),$ccl,$mode); + // element has one sentence + $this->assertEquals(1,count($this->getXmlElement($result,'chunk')->children())); + $this->assertEquals('sentence',$this->getXmlElement($result,'chunk')->children()[0]->getName()); + // element is empty & has attributes properly set + $sentence = $this->getXmlElement($result,'chunk')->{'sentence'}; + $this->assertEquals('',$sentence); + $this->assertEquals($sentenceId,$this->getXmlAttribute($sentence,'id')); + + $mode = CclWriter::$CCLREL; + $result = $privateMethod->invoke(new CclWriter(),$ccl,$mode); + // element has one sentence + $this->assertEquals(1,count($this->getXmlElement($result,'chunk')->children())); + $this->assertEquals('sentence',$this->getXmlElement($result,'chunk')->children()[0]->getName()); + // element is empty & has attributes properly set + $sentence = $this->getXmlElement($result,'chunk')->{'sentence'}; + $this->assertEquals('',$sentence); + $this->assertEquals($sentenceId,$this->getXmlAttribute($sentence,'id')); + + $mode = CclWriter::$REL; + $expectedXml = $this->getExpectedEmptyRelationList(); + $result = $privateMethod->invoke(new CclWriter(),$ccl,$mode); + $this->assertEquals($expectedXml,$result); + + } // testCclWithEmptySentenceMakesSentenceSkeletonWithId() + + public function testCclInCclModeExportsAllTokensFields() { + + $mode = CclWriter::$CCL; + $chunkId = '15'; + $chunkType = 'ChType'; + $sentenceId = '234'; + $tokenOrth = 'token orth'; + $tokenPropKey = 'token prop key'; + $tokenPropValue = 'token prop value'; + $tokenProp = array($tokenPropKey=>$tokenPropValue); + $lexDisamb = true; + $lexBase = 'base'; + $lexCtag = 'ctag'; + $channelType = 'chType'; + $channelNumber = 'chNumber'; + $tokenChannel = array($channelType=>$channelNumber); + $mockLexeme = $this->createMockLexeme($lexDisamb,$lexBase,$lexCtag); + $mockToken = $this->createMockToken($tokenOrth,false,$tokenProp,array($mockLexeme),$tokenChannel); + $mockSentence = $this->createMockSentence($sentenceId,array($mockToken)); + $mockChunk = $this->createMockChunk($chunkId,$chunkType,array($mockSentence)); + $ccl = $this->createMockCclDocument(array($mockChunk)); + + // private method need reflection to tests + $privateMethod = new ReflectionMethod('CclWriter','makeXmlData'); + $privateMethod->setAccessible(True); + + $result = $privateMethod->invoke(new CclWriter(),$ccl,$mode); + // element has one token element + // and one ns selftag if property ns inside token is set + $this->assertEquals(1,count($this->getXmlElement($result,'chunk')->{'sentence'}->children())); + $this->assertEquals('tok',$this->getXmlElement($result,'chunk')->{'sentence'}->children()[0]->getName()); + // element has elements orth and array prop set + $tok = $this->getXmlElement($result,'chunk')->{'sentence'}->{'tok'}; + $this->assertEquals('',$tok); + // orth token orth + $this->assertEquals($tokenOrth,$tok->{'orth'}); + // prop token prop value + $prop = $tok->{'prop'}; + $this->assertEquals($tokenPropKey,$this->getXmlAttribute($prop,'key')); + $this->assertEquals($tokenPropValue,$prop); + // lexeme basectag + $lexeme = $tok->{'lex'}; + $this->assertEquals('',$lexeme); + $this->assertEquals('1',$this->getXmlAttribute($lexeme,'disamb')); + $this->assertEquals($lexBase,$lexeme->{'base'}); + $this->assertEquals($lexCtag,$lexeme->{'ctag'}); + // channel chNumber + $this->assertEquals($channelType,$this->getXmlAttribute($tok->{'ann'},'chan')); + $this->assertEquals($channelNumber,$tok->{'ann'}); + + // if token->ns is true extra element after token is set + $mockToken->ns = true; + $result = $privateMethod->invoke(new CclWriter(),$ccl,$mode); + $this->assertEquals(2,count($this->getXmlElement($result,'chunk')->{'sentence'}->children())); + $this->assertEquals('ns',$this->getXmlElement($result,'chunk')->{'sentence'}->children()[1]->getName()); + + } // testCclInCclModeExportsAllTokensFields() + + public function testCclInCclrelModeExportsAllTokensAndRelationsFields() { + + $mode = CclWriter::$CCLREL; + $chunkId = '15'; + $chunkType = 'ChType'; + $sentenceId = '234'; + $tokenOrth = 'token orth'; + $tokenPropKey = 'token prop key'; + $tokenPropValue = 'token prop value'; + $tokenProp = array($tokenPropKey=>$tokenPropValue); + $lexDisamb = true; + $lexBase = 'base'; + $lexCtag = 'ctag'; + $channelType = 'chType'; + $channelNumber = 'chNumber'; + $tokenChannel = array($channelType=>$channelNumber); + $relName = 'relation name'; + $relSet = 'relation Set'; + $relFromSentence = 'from sentence'; + $relFromType = 'from type'; + $relFromChannel = 'from channel'; + $relToSentence = 'to sentence'; + $relToType = 'to type'; + $relToChannel = 'to channel'; + $mockLexeme = $this->createMockLexeme($lexDisamb,$lexBase,$lexCtag); + $mockToken = $this->createMockToken($tokenOrth,false,$tokenProp,array($mockLexeme),$tokenChannel); + $mockSentence = $this->createMockSentence($sentenceId,array($mockToken)); + $mockChunk = $this->createMockChunk($chunkId,$chunkType,array($mockSentence)); + $mockRelation = $this->createMockCclRelation($relName,$relSet,$relFromSentence,$relFromType,$relFromChannel,$relToSentence,$relToType,$relToChannel); + $ccl = $this->createMockCclDocument(array($mockChunk),array($mockRelation)); + + // private method need reflection to tests + $privateMethod = new ReflectionMethod('CclWriter','makeXmlData'); + $privateMethod->setAccessible(True); + + $result = $privateMethod->invoke(new CclWriter(),$ccl,$mode); + // element has one token element + // and one ns selftag if property ns inside token is set + $this->assertEquals(1,count($this->getXmlElement($result,'chunk')->{'sentence'}->children())); + $this->assertEquals('tok',$this->getXmlElement($result,'chunk')->{'sentence'}->children()[0]->getName()); + // element has elements orth and array prop set + $tok = $this->getXmlElement($result,'chunk')->{'sentence'}->{'tok'}; + $this->assertEquals('',$tok); + // orth token orth + $this->assertEquals($tokenOrth,$tok->{'orth'}); + // prop token prop value + $prop = $tok->{'prop'}; + $this->assertEquals($tokenPropKey,$this->getXmlAttribute($prop,'key')); + $this->assertEquals($tokenPropValue,$prop); + // lexeme basectag + $lexeme = $tok->{'lex'}; + $this->assertEquals('',$lexeme); + $this->assertEquals('1',$this->getXmlAttribute($lexeme,'disamb')); + $this->assertEquals($lexBase,$lexeme->{'base'}); + $this->assertEquals($lexCtag,$lexeme->{'ctag'}); + // channel chNumber + $this->assertEquals($channelType,$this->getXmlAttribute($tok->{'ann'},'chan')); + $this->assertEquals($channelNumber,$tok->{'ann'}); + // relations data + // element has one rel element + $this->assertEquals(1,count($this->getXmlElement($result,'relations'))); + // has two attributes and two children + $rel = $this->getXmlElement($result,'relations')->{'rel'}; + $this->assertEquals($relName,$this->getXmlAttribute($rel,'name')); + $this->assertEquals($relSet,$this->getXmlAttribute($rel,'set')); + $this->assertEquals(2,count($rel->children())); + $this->assertEquals('from',$rel->children()[0]->getName()); + $this->assertEquals('to',$rel->children()[1]->getName()); + // has 2 attributes and value + $from = $rel->{'from'}; + $this->assertEquals($relFromSentence,$this->getXmlAttribute($from,'sent')); + $this->assertEquals($relFromType,$this->getXmlAttribute($from,'chan')); + $this->assertEquals($relFromChannel,$from); + // has 2 attributes and value + $to = $rel->{'to'}; + $this->assertEquals($relToSentence,$this->getXmlAttribute($to,'sent')); + $this->assertEquals($relToType,$this->getXmlAttribute($to,'chan')); + $this->assertEquals($relToChannel,$to); + + + // if token->ns is true extra element after token is set + $mockToken->ns = true; + $result = $privateMethod->invoke(new CclWriter(),$ccl,$mode); + $this->assertEquals(2,count($this->getXmlElement($result,'chunk')->{'sentence'}->children())); + $this->assertEquals('ns',$this->getXmlElement($result,'chunk')->{'sentence'}->children()[1]->getName()); + + } // testCclInCclrelModeExportsAllTokensAndRelationsFields() + + public function testCclInRelModeExportsAllRelationsFields() { + + $mode = CclWriter::$REL; + + $relName = 'relation name'; + $relSet = 'relation Set'; + $relFromSentence = 'from sentence'; + $relFromType = 'from type'; + $relFromChannel = 'from channel'; + $relToSentence = 'to sentence'; + $relToType = 'to type'; + $relToChannel = 'to channel'; + $mockRelation = $this->createMockCclRelation($relName,$relSet,$relFromSentence,$relFromType,$relFromChannel,$relToSentence,$relToType,$relToChannel); + $ccl = $this->createMockCclDocument(array(),array($mockRelation)); + + // private method need reflection to tests + $privateMethod = new ReflectionMethod('CclWriter','makeXmlData'); + $privateMethod->setAccessible(True); + + $result = $privateMethod->invoke(new CclWriter(),$ccl,$mode); + // + // + // from channel + // to channel + // + // + // element has one rel element + $this->assertEquals(1,count($this->getXmlElement($result,'rel'))); + // has two attributes and two children + $rel = $this->getXmlElement($result,'rel'); + $this->assertEquals($relName,$this->getXmlAttribute($rel,'name')); + $this->assertEquals($relSet,$this->getXmlAttribute($rel,'set')); + $this->assertEquals(2,count($rel->children())); + $this->assertEquals('from',$rel->children()[0]->getName()); + $this->assertEquals('to',$rel->children()[1]->getName()); + // has 2 attributes and value + $from = $rel->{'from'}; + $this->assertEquals($relFromSentence,$this->getXmlAttribute($from,'sent')); + $this->assertEquals($relFromType,$this->getXmlAttribute($from,'chan')); + $this->assertEquals($relFromChannel,$from); + // has 2 attributes and value + $to = $rel->{'to'}; + $this->assertEquals($relToSentence,$this->getXmlAttribute($to,'sent')); + $this->assertEquals($relToType,$this->getXmlAttribute($to,'chan')); + $this->assertEquals($relToChannel,$to); + + } // testCclInRelModeExportsAllRelationsFields() + + public function testFullCclDataProperlyFormatsAsXml() { + + $ccl = $this->generateFullCclData(); + + // private method need reflection to tests + $privateMethod = new ReflectionMethod('CclWriter','makeXmlData'); + $privateMethod->setAccessible(True); + + $mode = CclWriter::$CCLREL; // for $CCLREL are both sections + $expectedXml = $this->generateExpectedXMLForFullCclData(); + $result = $privateMethod->invoke(new CclWriter(),$ccl,$mode); + $this->assertEquals($expectedXml,$result); + + } // testFullCclDataProperlyFormatsAsXml() + + public function testLemmaDataGeneratesPropXml() { + + $annotation_lemma = array ( + "type" => "annotation_type", + "lemma" => "annotation_lemma" + ); + $token = new CclToken(); + $token->setAnnotationLemma($annotation_lemma); + $sentence = new CclSentence(); + $sentence->addToken($token); + $chunk = new CclChunk(); + $chunk->addSentence($sentence); + $ccl = new CclDocument(); + $ccl->addChunk($chunk); + $ccl->addToken($token); + + // private method need reflection to tests + $privateMethod = new ReflectionMethod('CclWriter','makeXmlData'); + $privateMethod->setAccessible(True); + + $mode = CclWriter::$CCLREL; // for $CCLREL are both sections + $expectedXmlLine = + "@" // regexp delimiter + .' annotation_lemma'."\n" + ."@"; + + $result = $privateMethod->invoke(new CclWriter(),$ccl,$mode); + // test if is above line in result + $this->assertRegexp($expectedXmlLine,$result); + + } // testLemmaDataGeneratesPropXml() + +// protected function formatPropToXML($propTable) {...} + + public function testInValidPropGenerateEmptyXml() { + + // private method need reflection to tests + $privateMethod = new ReflectionMethod('CclWriter','formatPropToXML'); + $privateMethod->setAccessible(True); + + $expectedEmptyXml = ""; + $result = $privateMethod->invoke(new CclWriter(),null); + $this->assertEquals($expectedEmptyXml,$result); + + $result = $privateMethod->invoke(new CclWriter(),array()); + $this->assertEquals($expectedEmptyXml,$result); + + } // testInValidPropGenerateEmptyXml() + + public function testValidPropGeneratePropXmlTagElements() { + + // private method need reflection to tests + $privateMethod = new ReflectionMethod('CclWriter','formatPropToXML'); + $privateMethod->setAccessible(True); + + // single property + $prop = array( "key" => "value" ); + $expectedXml = ' value'."\n"; + $result = $privateMethod->invoke(new CclWriter(),$prop); + $this->assertEquals($expectedXml,$result); + + // 2 props in one line - ;; is separator + $prop = array( "key" => "val1;;val2" ); + $expectedXml = ' val1'."\n" + .' val2'."\n"; + $result = $privateMethod->invoke(new CclWriter(),$prop); + $this->assertEquals($expectedXml,$result); + + // more than 2 values are throwed silently + $prop = array( "key" => "val1;;val2;;val3" ); + $expectedXml = ' val1'."\n" + .' val2'."\n"; + $result = $privateMethod->invoke(new CclWriter(),$prop); + $this->assertEquals($expectedXml,$result); + + } // testValidPropGeneratePropXmlTagElements() + + +} // CclWriterTest class + +?> diff --git a/public_html/css.php b/public_html/css.php index b583a272..726cc586 100644 --- a/public_html/css.php +++ b/public_html/css.php @@ -8,14 +8,13 @@ $enginePath = realpath(__DIR__ . "/../engine/"); require_once($enginePath . "/settings.php"); -require_once($enginePath . '/include.php'); -Config::Config()->put_path_engine($enginePath); -Config::Config()->put_localConfigFilename(realpath($enginePath . "/../config/").DIRECTORY_SEPARATOR."config.local.php"); +Config::Cfg()->put_path_engine($enginePath); +Config::Cfg()->put_localConfigFilename(realpath($enginePath . "/../config/").DIRECTORY_SEPARATOR."config.local.php"); /********************************************************************8 * Połączenie z bazą danych (nowy sposób) */ -$db = new Database(Config::Config()->get_dsn()); +$db = new Database(Config::Cfg()->get_dsn()); $db->set_encoding('utf8'); /********************************************************************/ diff --git a/public_html/image.php b/public_html/image.php index fdf19d4c..a02f8094 100644 --- a/public_html/image.php +++ b/public_html/image.php @@ -8,14 +8,13 @@ $enginePath = realpath(__DIR__ . "/../engine/"); require_once($enginePath."/settings.php"); -require_once($enginePath.'/include.php'); -Config::Config()->put_path_engine($enginePath); -Config::Config()->put_localConfigFilename(realpath($enginePath . "/../config/").DIRECTORY_SEPARATOR."config.local.php"); +Config::Cfg()->put_path_engine($enginePath); +Config::Cfg()->put_localConfigFilename(realpath($enginePath . "/../config/").DIRECTORY_SEPARATOR."config.local.php"); /********************************************************************8 * Połączenie z bazą danych (nowy sposób) */ -$db=new Database(Config::Config()->get_dsn()); +$db=new Database(Config::Cfg()->get_dsn()); $db->set_encoding('utf8'); /********************************************************************/ ob_start(); @@ -25,7 +24,7 @@ $width = isset($_GET['width']) ? intval($_GET['width']) : 0; if ($row){ - $filename = Config::Config()->get_path_secured_data() . "/images/" . $row['id']."_".$row['hash_name']; + $filename = Config::Cfg()->get_path_secured_data() . "/images/" . $row['id']."_".$row['hash_name']; $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); if ($ext == "png" ) diff --git a/public_html/index.php b/public_html/index.php index 9455fe13..256b9614 100644 --- a/public_html/index.php +++ b/public_html/index.php @@ -11,27 +11,25 @@ require_once($loaderName); } ob_start(); +$enginePath = realpath(__DIR__ . "/../engine/"); +require_once($enginePath."/settings.php"); try{ + // TEMP TO REMOVE ini_set('memory_limit', '2048M'); - /********************************************************************/ - - $enginePath = realpath(__DIR__ . "/../engine/"); - require_once($enginePath."/settings.php"); - require_once($enginePath.'/include.php'); /*** reset cookies if &resetCOOKIES=1 is in page URL ***/ CookieResetter::resetAllCookies(); //DebugLogger::logAllDynamicVariables(); // log all dynamic HTTP variables - Config::Config()->put_path_engine($enginePath); - Config::Config()->put_localConfigFilename(realpath($enginePath."/../config/").DIRECTORY_SEPARATOR."config.local.php"); + Config::Cfg()->put_path_engine($enginePath); + Config::Cfg()->put_localConfigFilename(realpath($enginePath."/../config/").DIRECTORY_SEPARATOR."config.local.php"); - if ( !file_exists(Config::Config()->get_path_engine() . "/templates_c") ){ - throw new Exception("Folder '" . Config::Config()->get_path_engine() . "/templates_c' does not exist"); + if ( !file_exists(Config::Cfg()->get_path_engine() . "/templates_c") ){ + throw new Exception("Folder '" . Config::Cfg()->get_path_engine() . "/templates_c' does not exist"); } - if ( Config::Config()->get_offline() ){ + if ( Config::Cfg()->get_offline() ){ $variables = array(); $inforex = new InforexWeb(); $inforex->doPage("offline", $variables); @@ -41,16 +39,14 @@ ob_clean(); $p = new InforexWeb(); - $db = new Database(Config::Config()->get_dsn(), Config::Config()->get_log_sql(), Config::Config()->get_log_output(), Config::Config()->get_db_charset()); + $db = new Database(Config::Cfg()->get_dsn(), Config::Cfg()->get_log_sql(), Config::Cfg()->get_log_output(), Config::Cfg()->get_db_charset()); - $auth = new UserAuthorize(Config::Config()->get_dsn()); + $auth = new UserAuthorize(Config::Cfg()->get_dsn()); $auth->authorize(isset($_POST['logout']) && ($_POST['logout']=="1")); $user = $auth->getUserData(); - $corpus = RequestLoader::loadCorpus(); - // federation login is enabled - if(Config::Config()->get_federationLoginUrl()){ + if(Config::Cfg()->get_federationLoginUrl()){ $clarinUser = $auth->getClarinUser(); // try to connect to local account @@ -68,14 +64,15 @@ } } - chdir("../engine"); + // load corpus after finally set $user data + $corpus = RequestLoader::loadCorpus(); + + chdir(__DIR__ . "/../engine/"); $p->execute(); print trim(ob_get_clean()); } catch(Exception $e){ - print "Unexpected exception: " . $e->getMessage() . ""; - print "
    ".$e->getTraceAsString()."
    "; - print trim(ob_get_clean()); + UncaughtExceptionService::UncaughtException($e); } diff --git a/public_html/js/page_corpus_export.js b/public_html/js/page_corpus_export.js index 1497604a..a9fc6efd 100644 --- a/public_html/js/page_corpus_export.js +++ b/public_html/js/page_corpus_export.js @@ -187,28 +187,43 @@ function setStateForValue(element,value,on=true){ } // setStateForValue() /** - * set all annotations for value id to checked state + * set all annotations set for value id to checked state * * @param form - extractor form object * @param value - value of "value" attr, checked annotations * **/ -function setAnnotationsForValue(form,value) { +function setAnnotationsSetForValue(form,value) { $("input[type=checkbox].group_cb",form).each(function(index,element){ setStateForValue(element,value,true); }); -} // setAnnotationsForValue() +} // setAnnotationsSetForValue() /** - * set all lemmas and attributes for value id to unchecked state + * set all annotations subsets for value id to checked state + * + * @param form - extractor form object + * @param value - value of "value" attr, checked annotations + * + **/ +function setAnnotationsSubsetForValue(form,value) { + + $("input[type=checkbox].subset_cb",form).each(function(index,element){ + setStateForValue(element,value,true); + }); + +} // setAnnotationsSubsetForValue() + +/** + * set all lemmas and attributes sets for value id to unchecked state * * @param form - extractor form object * @param value - value of "value" attr, unchecked lemmas & attributtes * **/ -function unsetLemmasAndAttributesForValue(form,value) { +function unsetLemmasAndAttributesSetsForValue(form,value) { $("input[type=checkbox].lemma_group_cb",form).each(function(index,element){ setStateForValue(element,value,false); @@ -217,7 +232,25 @@ function unsetLemmasAndAttributesForValue(form,value) { setStateForValue(element,value,false); }); -} // unsetLemmasAndAttributesForValue() +} // unsetLemmasAndAttributesSetsForValue() + +/** + * set all lemmas and attributes subsets for value id to unchecked state + * + * @param form - extractor form object + * @param value - value of "value" attr, unchecked lemmas & attributtes + * + **/ +function unsetLemmasAndAttributesSubsetsForValue(form,value) { + + $("input[type=checkbox].lemma_subset_cb",form).each(function(index,element){ + setStateForValue(element,value,false); + }); + $("input[type=checkbox].attribute_subset_cb",form).each(function(index,element){ + setStateForValue(element,value,false); + }); + +} // unsetLemmasAndAttributesSubsetsForValue() /** * set action to dynamically created extractor form, binding to input @@ -234,15 +267,23 @@ function setActionToFollowAnnotationAfterLemmaAndAttrs(extractorForm){ if(!extractorForm) return; extractorForm.on('click',"input[type=checkbox]:checked.lemma_group_cb",function(){ - setAnnotationsForValue(extractorForm,$(this).attr("value")); + setAnnotationsSetForValue(extractorForm,$(this).attr("value")); }); extractorForm.on('click',"input[type=checkbox]:checked.attribute_group_cb",function(){ - setAnnotationsForValue(extractorForm,$(this).attr("value")); + setAnnotationsSetForValue(extractorForm,$(this).attr("value")); }); extractorForm.on('click',"input[type=checkbox]:unchecked.group_cb",function(){ - unsetLemmasAndAttributesForValue(extractorForm,$(this).attr("value")); + unsetLemmasAndAttributesSetsForValue(extractorForm,$(this).attr("value")); + }); + extractorForm.on('click',"input[type=checkbox]:checked.lemma_subset_cb",function(){ + setAnnotationsSubsetForValue(extractorForm,$(this).attr("value")); + }); + extractorForm.on('click',"input[type=checkbox]:checked.attribute_subset_cb",function(){ + setAnnotationsSubsetForValue(extractorForm,$(this).attr("value")); + }); + extractorForm.on('click',"input[type=checkbox]:unchecked.subset_cb",function(){ + unsetLemmasAndAttributesSubsetsForValue(extractorForm,$(this).attr("value")); }); - } // setActionToFollowAnnotationAfterLemmaAndAttrs() diff --git a/public_html/js/page_report_agreement.js b/public_html/js/page_report_agreement.js index bde1a63c..d7018391 100644 --- a/public_html/js/page_report_agreement.js +++ b/public_html/js/page_report_agreement.js @@ -8,6 +8,9 @@ * Przypisanie akcji po wczytaniu się strony. */ $(document).ready(function(){ + var url = $.url(window.location.href); + var corpus_id = url.param('corpus'); + loadAnnotationTypesFromTemplates(corpus_id); assign_click_legend(); assign_annotation_triggers(); assign_more_less(); diff --git a/public_html/js/page_report_annotation_attributes.js b/public_html/js/page_report_annotation_attributes.js index 8b8e9e37..bfb1e35a 100644 --- a/public_html/js/page_report_annotation_attributes.js +++ b/public_html/js/page_report_annotation_attributes.js @@ -6,6 +6,9 @@ $(document).ready(function(){ + var url = $.url(window.location.href); + var corpus_id = url.param('corpus'); + loadAnnotationTypesFromTemplates(corpus_id); setupAnnotationTypeTree(); setupAnnotationMode(); @@ -229,4 +232,4 @@ function updateSaveButtonStatus(){ button.addClass("btn-default"); button.removeClass("btn-danger"); } -} \ No newline at end of file +} diff --git a/public_html/js/page_report_annotation_lemma.js b/public_html/js/page_report_annotation_lemma.js index 54706485..784d7033 100644 --- a/public_html/js/page_report_annotation_lemma.js +++ b/public_html/js/page_report_annotation_lemma.js @@ -5,6 +5,9 @@ */ $(document).ready(function(){ + var url = $.url(window.location.href); + var corpus_id = url.param('corpus'); + loadAnnotationTypesFromTemplates(corpus_id); assignButtonAutofillClick(); assignButtonSaveAllClick(); @@ -246,4 +249,4 @@ function updateSaveButtonStatus(){ button.addClass("btn-default"); button.removeClass("btn-danger"); } -} \ No newline at end of file +} diff --git a/public_html/js/page_report_annotation_tree_loader.js b/public_html/js/page_report_annotation_tree_loader.js new file mode 100644 index 00000000..1b749a31 --- /dev/null +++ b/public_html/js/page_report_annotation_tree_loader.js @@ -0,0 +1,145 @@ +/** + * Part of the Inforex project + * Copyright (C) 2013 Michał Marcińczuk, Jan Kocoń, Marcin Ptak + * Wrocław University of Technology + */ + +var url = $.url(window.location.href); +var corpus_id = url.param("corpus"); + +function createSetRowFromTemplate(container,setId,setName) { + + /* from HTML template in DOM named id='setRowTpl' + * creates code of set row for parametres setId,setName + * and place it on the end of container element + */ + const setRowTemplateId = "setRowTpl"; + let setRow = null; + const template = document.querySelector("#"+setRowTemplateId); + if(template) { + setRow = template.content.cloneNode(true); + if(setRow){ + setRow.querySelector("input").setAttribute("name","layerId-"+setId); + setRow.querySelector(".layerName").innerText = setName; + if(container) { + container.append(setRow); + } + } else { + console.log("Cannot clone DOM element for template with id="+setRowTemplateId); + } + } else { + console.log("Cannot create DOM element from template with id="+setRowTemplateId); + } + +} // createSetRowfromTemplate() + +function createSubsetRowFromTemplate(container,subsetId,subsetName) { + + /* from HTML template in DOM named id='subsetRowTpl' + * creates code of subset row for parametres subsetId, subsetName + * and place it on the end of container element + */ + const subsetRowTemplateId = "subsetRowTpl"; + let subsetRow = null; + const template = document.querySelector("#"+subsetRowTemplateId); + if(template) { + subsetRow = template.content.cloneNode(true); + if(subsetRow){ + subsetRow.querySelector("input").setAttribute("name","subsetId-"+subsetId); + subsetRow.querySelector("tr").setAttribute("subsetid",subsetId); + subsetRow.querySelector(".layerName").innerText = subsetName; + if(container) { + container.append(subsetRow); + } + } else { + console.log("Cannot clone DOM element for template with id="+subsetRowTemplateId); + } + } else { + console.log("Cannot create DOM element from template with id="+subsetRowTemplateId); + } + +} // createSubsetRowfromTemplate() + +function createTypeRowFromTemplate(container,typeId,typeName) { + + /* from HTML template in DOM named id='typeRowTpl' + * creates code of type row for parametres typeId, typeName + * and place it on the end of container element + */ + const typeRowTemplateId = "typeRowTpl"; + const MAX_TYPES_NAME_LABEL = "..."; + let typeRow = null; + const template = document.querySelector("#"+typeRowTemplateId); + if(template) { + typeRow = template.content.cloneNode(true); + if(typeRow){ + if(typeName==MAX_TYPES_NAME_LABEL) { + /* remove checkbox for limit threshold */ + elem = typeRow.querySelector("input"); + if(elem) { + elem.parentElement.removeChild(elem); + } + } else { /* type under limit */ + typeRow.querySelector("input").setAttribute("name","typeId-"+typeId); + } + typeRow.querySelector("tr").setAttribute("typeid",typeId); + typeRow.querySelector(".layerName").innerText = typeName; + if(container) { + container.append(typeRow); + } + } else { + console.log("Cannot clone DOM element for template with id="+typeRowTemplateId); + } + } else { + console.log("Cannot create DOM element from template with id="+typeRowTemplateId); + } + +} // createTypeRowFromTemplate() + +/** + * loads rows with sets, subsets & types of annotations from templates + * and pure JSON data from ajax request + */ +function loadAnnotationTypesFromTemplates(corpus_id) { + + // loading all data from ajax service + const serviceName = "annotation_type_tree"; + const getTypesSuccess = function(data) { + + // create rows for sets, subsets and types + if(!data){ return; } + if(data.length==0){ return; } + // element, which holds all rows + const container = $(".annotationTypesTree"); + // remove default content for empty set + $(container).find("tr").remove(); + // array of setId => set_array, + $.each(data,function(setId,setArray){ + const setName = setArray.name; + createSetRowFromTemplate(container,setId,setName); + $.each(setArray,function(subsetId,subsetArray){ + if(subsetId!='name'){ + const subsetName = subsetArray.name; + createSubsetRowFromTemplate(container,subsetId,subsetName); + $.each(subsetArray,function(typeId,typeName){ + if(typeId!='name'){ + createTypeRowFromTemplate(container,typeId,typeName); + }; // typeId<>'name' + }); // each subsetArray + }; // subsetId <> 'name' + }); // each setArray + }); // each data + + }; + const getTypesError = function() { + console.log("Error on ajax request for "+serviceName); + }; + doAjaxSync( serviceName , + { 'corpusId' : corpus_id }, + getTypesSuccess, + getTypesError, + null // getTypesComplete + ); + +} // loadAnnotationTypesFromTemplates() + diff --git a/public_html/js/page_report_annotator.js b/public_html/js/page_report_annotator.js index 4f6325c5..4c779493 100644 --- a/public_html/js/page_report_annotator.js +++ b/public_html/js/page_report_annotator.js @@ -12,6 +12,9 @@ var globalSelection = null; $(function(){ + var url = $.url(window.location.href); + var corpus_id = url.param('corpus'); + loadAnnotationTypesFromTemplates(corpus_id); setupAnnotationMode(); wAnnotationDetails = new WidgetAnnotation("#annotation-details", function(){ diff --git a/public_html/js/page_report_preview.js b/public_html/js/page_report_preview.js index 3a142b95..5165b235 100644 --- a/public_html/js/page_report_preview.js +++ b/public_html/js/page_report_preview.js @@ -9,10 +9,12 @@ var wRelationSets = null; var url = $.url(window.location.href); var corpus_id = url.param("corpus"); var report_id = url.param("id"); + /** * Przypisanie akcji po wczytaniu się strony. */ $(document).ready(function(){ + loadAnnotationTypesFromTemplates(corpus_id); wRelationSets = new WidgetRelationSetSelector("#relation-sets", corpus_id); wRelationSets.load(); diff --git a/public_html/js/page_report_relation_agreement.js b/public_html/js/page_report_relation_agreement.js index 8bddba10..1796db88 100644 --- a/public_html/js/page_report_relation_agreement.js +++ b/public_html/js/page_report_relation_agreement.js @@ -9,6 +9,7 @@ var corpus_id = url.param('corpus'); * Przypisanie akcji po wczytaniu się strony. */ $(function(){ + loadAnnotationTypesFromTemplates(corpus_id); assign_click_legend(); assign_annotation_triggers(); assign_more_less();