Zmiana numeru wersji na 2.6, testy jednostkowe niektórych klas (PHPUnit),
dodanych wiele komentarzy dotyczących metod oraz atrybutów (Doxygen),
aktualizacja instrukcji instalacji i aktualizacji.
 
	
	
	
	
	
	
		
		8 files added
	
		
		15 files modified
	
	
 
	
	
	
	
	
	
	
	
| New file | 
 |  |  | 
 |  |  | language: php  | 
 |  |  | php: | 
 |  |  |   - 5.5 | 
 |  |  |   - 5.4 | 
 |  |  |   - 5.3 | 
 |  |  |   - 5.2 | 
 |  |  |  | 
 |  |  | script: phpunit --coverage-text | 
 
| New file | 
 |  |  | 
 |  |  | #--------------------------------------------------------------------------- | 
 |  |  | # Project related configuration options | 
 |  |  | #--------------------------------------------------------------------------- | 
 |  |  | DOXYFILE_ENCODING      = UTF-8 | 
 |  |  | PROJECT_NAME           = "Bot Gadu-Gadu" | 
 |  |  | PROJECT_NUMBER         =  | 
 |  |  | OUTPUT_DIRECTORY       = docs | 
 |  |  | CREATE_SUBDIRS         = NO | 
 |  |  | OUTPUT_LANGUAGE        = Polish | 
 |  |  | BRIEF_MEMBER_DESC      = YES | 
 |  |  | REPEAT_BRIEF           = YES | 
 |  |  | ABBREVIATE_BRIEF       = "The $name class" \ | 
 |  |  |                          "The $name widget" \ | 
 |  |  |                          "The $name file" \ | 
 |  |  |                          is \ | 
 |  |  |                          provides \ | 
 |  |  |                          specifies \ | 
 |  |  |                          contains \ | 
 |  |  |                          represents \ | 
 |  |  |                          a \ | 
 |  |  |                          an \ | 
 |  |  |                          the | 
 |  |  | ALWAYS_DETAILED_SEC    = NO | 
 |  |  | INLINE_INHERITED_MEMB  = NO | 
 |  |  | FULL_PATH_NAMES        = YES | 
 |  |  | STRIP_FROM_PATH        =  | 
 |  |  | STRIP_FROM_INC_PATH    =  | 
 |  |  | SHORT_NAMES            = NO | 
 |  |  | JAVADOC_AUTOBRIEF      = NO | 
 |  |  | QT_AUTOBRIEF           = NO | 
 |  |  | MULTILINE_CPP_IS_BRIEF = NO | 
 |  |  | INHERIT_DOCS           = YES | 
 |  |  | SEPARATE_MEMBER_PAGES  = NO | 
 |  |  | TAB_SIZE               = 8 | 
 |  |  | ALIASES                =  | 
 |  |  | OPTIMIZE_OUTPUT_FOR_C  = NO | 
 |  |  | OPTIMIZE_OUTPUT_JAVA   = NO | 
 |  |  | OPTIMIZE_FOR_FORTRAN   = NO | 
 |  |  | OPTIMIZE_OUTPUT_VHDL   = NO | 
 |  |  | EXTENSION_MAPPING      =  | 
 |  |  | BUILTIN_STL_SUPPORT    = NO | 
 |  |  | CPP_CLI_SUPPORT        = NO | 
 |  |  | SIP_SUPPORT            = NO | 
 |  |  | IDL_PROPERTY_SUPPORT   = YES | 
 |  |  | DISTRIBUTE_GROUP_DOC   = NO | 
 |  |  | SUBGROUPING            = YES | 
 |  |  | TYPEDEF_HIDES_STRUCT   = NO | 
 |  |  | SYMBOL_CACHE_SIZE      = 0 | 
 |  |  |  | 
 |  |  | #--------------------------------------------------------------------------- | 
 |  |  | # Build related configuration options | 
 |  |  | #--------------------------------------------------------------------------- | 
 |  |  | EXTRACT_ALL            = NO | 
 |  |  | EXTRACT_PRIVATE        = YES | 
 |  |  | EXTRACT_STATIC         = YES | 
 |  |  | EXTRACT_LOCAL_CLASSES  = YES | 
 |  |  | EXTRACT_LOCAL_METHODS  = YES | 
 |  |  | EXTRACT_ANON_NSPACES   = NO | 
 |  |  | HIDE_UNDOC_MEMBERS     = NO | 
 |  |  | HIDE_UNDOC_CLASSES     = NO | 
 |  |  | HIDE_FRIEND_COMPOUNDS  = NO | 
 |  |  | HIDE_IN_BODY_DOCS      = NO | 
 |  |  | INTERNAL_DOCS          = NO | 
 |  |  | CASE_SENSE_NAMES       = NO | 
 |  |  | HIDE_SCOPE_NAMES       = NO | 
 |  |  | SHOW_INCLUDE_FILES     = YES | 
 |  |  | FORCE_LOCAL_INCLUDES   = NO | 
 |  |  | INLINE_INFO            = YES | 
 |  |  | SORT_MEMBER_DOCS       = YES | 
 |  |  | SORT_BRIEF_DOCS        = NO | 
 |  |  | SORT_MEMBERS_CTORS_1ST = NO | 
 |  |  | SORT_GROUP_NAMES       = NO | 
 |  |  | SORT_BY_SCOPE_NAME     = NO | 
 |  |  | GENERATE_TODOLIST      = YES | 
 |  |  | GENERATE_TESTLIST      = YES | 
 |  |  | GENERATE_BUGLIST       = YES | 
 |  |  | GENERATE_DEPRECATEDLIST= YES | 
 |  |  | ENABLED_SECTIONS       =  | 
 |  |  | MAX_INITIALIZER_LINES  = 30 | 
 |  |  | SHOW_USED_FILES        = YES | 
 |  |  | SHOW_DIRECTORIES       = NO | 
 |  |  | SHOW_FILES             = YES | 
 |  |  | SHOW_NAMESPACES        = YES | 
 |  |  | FILE_VERSION_FILTER    =  | 
 |  |  | LAYOUT_FILE            =  | 
 |  |  |  | 
 |  |  | #--------------------------------------------------------------------------- | 
 |  |  | # configuration options related to warning and progress messages | 
 |  |  | #--------------------------------------------------------------------------- | 
 |  |  | QUIET                  = NO | 
 |  |  | WARNINGS               = YES | 
 |  |  | WARN_IF_UNDOCUMENTED   = YES | 
 |  |  | WARN_IF_DOC_ERROR      = YES | 
 |  |  | WARN_NO_PARAMDOC       = NO | 
 |  |  | WARN_FORMAT            = "$file:$line: $text" | 
 |  |  | WARN_LOGFILE           =  | 
 |  |  |  | 
 |  |  | #--------------------------------------------------------------------------- | 
 |  |  | # configuration options related to the input files | 
 |  |  | #--------------------------------------------------------------------------- | 
 |  |  | INPUT                  =  | 
 |  |  | INPUT_ENCODING         = UTF-8 | 
 |  |  | FILE_PATTERNS          = *.php | 
 |  |  | RECURSIVE              = YES | 
 |  |  | EXCLUDE                =  | 
 |  |  | EXCLUDE_SYMLINKS       = NO | 
 |  |  | EXCLUDE_PATTERNS       = */docs/* */data/* */tests/* */modules/* | 
 |  |  | EXCLUDE_SYMBOLS        =  | 
 |  |  | EXAMPLE_PATH           =  | 
 |  |  | EXAMPLE_PATTERNS       = * | 
 |  |  | EXAMPLE_RECURSIVE      = NO | 
 |  |  | IMAGE_PATH             =  | 
 |  |  | INPUT_FILTER           =  | 
 |  |  | FILTER_PATTERNS        =  | 
 |  |  | FILTER_SOURCE_FILES    = NO | 
 |  |  |  | 
 |  |  | #--------------------------------------------------------------------------- | 
 |  |  | # configuration options related to source browsing | 
 |  |  | #--------------------------------------------------------------------------- | 
 |  |  | SOURCE_BROWSER         = NO | 
 |  |  | INLINE_SOURCES         = NO | 
 |  |  | STRIP_CODE_COMMENTS    = YES | 
 |  |  | REFERENCED_BY_RELATION = NO | 
 |  |  | REFERENCES_RELATION    = NO | 
 |  |  | REFERENCES_LINK_SOURCE = YES | 
 |  |  | USE_HTAGS              = NO | 
 |  |  | VERBATIM_HEADERS       = YES | 
 |  |  |  | 
 |  |  | #--------------------------------------------------------------------------- | 
 |  |  | # configuration options related to the alphabetical class index | 
 |  |  | #--------------------------------------------------------------------------- | 
 |  |  | ALPHABETICAL_INDEX     = NO | 
 |  |  | COLS_IN_ALPHA_INDEX    = 5 | 
 |  |  | IGNORE_PREFIX          =  | 
 |  |  |  | 
 |  |  | #--------------------------------------------------------------------------- | 
 |  |  | # configuration options related to the HTML output | 
 |  |  | #--------------------------------------------------------------------------- | 
 |  |  | GENERATE_HTML          = YES | 
 |  |  | HTML_OUTPUT            = html | 
 |  |  | HTML_FILE_EXTENSION    = .html | 
 |  |  | HTML_HEADER            =  | 
 |  |  | HTML_FOOTER            =  | 
 |  |  | HTML_STYLESHEET        =  | 
 |  |  | HTML_TIMESTAMP         = YES | 
 |  |  | HTML_ALIGN_MEMBERS     = YES | 
 |  |  | HTML_DYNAMIC_SECTIONS  = NO | 
 |  |  | GENERATE_DOCSET        = NO | 
 |  |  | DOCSET_FEEDNAME        = "Doxygen generated docs" | 
 |  |  | DOCSET_BUNDLE_ID       = org.doxygen.Project | 
 |  |  | GENERATE_HTMLHELP      = NO | 
 |  |  | CHM_FILE               =  | 
 |  |  | HHC_LOCATION           =  | 
 |  |  | GENERATE_CHI           = NO | 
 |  |  | CHM_INDEX_ENCODING     =  | 
 |  |  | BINARY_TOC             = NO | 
 |  |  | TOC_EXPAND             = NO | 
 |  |  | GENERATE_QHP           = NO | 
 |  |  | QCH_FILE               =  | 
 |  |  | QHP_NAMESPACE          = org.doxygen.Project | 
 |  |  | QHP_VIRTUAL_FOLDER     = doc | 
 |  |  | QHP_CUST_FILTER_NAME   =  | 
 |  |  | QHP_CUST_FILTER_ATTRS  =  | 
 |  |  | QHP_SECT_FILTER_ATTRS  =  | 
 |  |  | QHG_LOCATION           =  | 
 |  |  | GENERATE_ECLIPSEHELP   = NO | 
 |  |  | ECLIPSE_DOC_ID         = org.doxygen.Project | 
 |  |  | DISABLE_INDEX          = NO | 
 |  |  | ENUM_VALUES_PER_LINE   = 4 | 
 |  |  | GENERATE_TREEVIEW      = NO | 
 |  |  | USE_INLINE_TREES       = NO | 
 |  |  | TREEVIEW_WIDTH         = 250 | 
 |  |  | FORMULA_FONTSIZE       = 10 | 
 |  |  | SEARCHENGINE           = YES | 
 |  |  | SERVER_BASED_SEARCH    = NO | 
 |  |  |  | 
 |  |  | #--------------------------------------------------------------------------- | 
 |  |  | # configuration options related to the LaTeX output | 
 |  |  | #--------------------------------------------------------------------------- | 
 |  |  | GENERATE_LATEX         = YES | 
 |  |  | LATEX_OUTPUT           = latex | 
 |  |  | LATEX_CMD_NAME         = latex | 
 |  |  | MAKEINDEX_CMD_NAME     = makeindex | 
 |  |  | COMPACT_LATEX          = NO | 
 |  |  | PAPER_TYPE             = a4wide | 
 |  |  | EXTRA_PACKAGES         =  | 
 |  |  | LATEX_HEADER           =  | 
 |  |  | PDF_HYPERLINKS         = YES | 
 |  |  | USE_PDFLATEX           = YES | 
 |  |  | LATEX_BATCHMODE        = NO | 
 |  |  | LATEX_HIDE_INDICES     = NO | 
 |  |  | LATEX_SOURCE_CODE      = NO | 
 |  |  |  | 
 |  |  | #--------------------------------------------------------------------------- | 
 |  |  | # configuration options related to the RTF output | 
 |  |  | #--------------------------------------------------------------------------- | 
 |  |  | GENERATE_RTF           = NO | 
 |  |  | RTF_OUTPUT             = rtf | 
 |  |  | COMPACT_RTF            = NO | 
 |  |  | RTF_HYPERLINKS         = NO | 
 |  |  | RTF_STYLESHEET_FILE    =  | 
 |  |  | RTF_EXTENSIONS_FILE    =  | 
 |  |  |  | 
 |  |  | #--------------------------------------------------------------------------- | 
 |  |  | # configuration options related to the man page output | 
 |  |  | #--------------------------------------------------------------------------- | 
 |  |  | GENERATE_MAN           = NO | 
 |  |  | MAN_OUTPUT             = man | 
 |  |  | MAN_EXTENSION          = .3 | 
 |  |  | MAN_LINKS              = NO | 
 |  |  |  | 
 |  |  | #--------------------------------------------------------------------------- | 
 |  |  | # configuration options related to the XML output | 
 |  |  | #--------------------------------------------------------------------------- | 
 |  |  | GENERATE_XML           = NO | 
 |  |  | XML_OUTPUT             = xml | 
 |  |  | XML_SCHEMA             =  | 
 |  |  | XML_DTD                =  | 
 |  |  | XML_PROGRAMLISTING     = YES | 
 |  |  |  | 
 |  |  | #--------------------------------------------------------------------------- | 
 |  |  | # configuration options for the AutoGen Definitions output | 
 |  |  | #--------------------------------------------------------------------------- | 
 |  |  | GENERATE_AUTOGEN_DEF   = NO | 
 |  |  |  | 
 |  |  | #--------------------------------------------------------------------------- | 
 |  |  | # configuration options related to the Perl module output | 
 |  |  | #--------------------------------------------------------------------------- | 
 |  |  | GENERATE_PERLMOD       = NO | 
 |  |  | PERLMOD_LATEX          = NO | 
 |  |  | PERLMOD_PRETTY         = YES | 
 |  |  | PERLMOD_MAKEVAR_PREFIX =  | 
 |  |  |  | 
 |  |  | #--------------------------------------------------------------------------- | 
 |  |  | # Configuration options related to the preprocessor | 
 |  |  | #--------------------------------------------------------------------------- | 
 |  |  | ENABLE_PREPROCESSING   = YES | 
 |  |  | MACRO_EXPANSION        = NO | 
 |  |  | EXPAND_ONLY_PREDEF     = NO | 
 |  |  | SEARCH_INCLUDES        = YES | 
 |  |  | INCLUDE_PATH           =  | 
 |  |  | INCLUDE_FILE_PATTERNS  =  | 
 |  |  | PREDEFINED             =  | 
 |  |  | EXPAND_AS_DEFINED      =  | 
 |  |  | SKIP_FUNCTION_MACROS   = YES | 
 |  |  |  | 
 |  |  | #--------------------------------------------------------------------------- | 
 |  |  | # Configuration::additions related to external references | 
 |  |  | #--------------------------------------------------------------------------- | 
 |  |  | TAGFILES               =  | 
 |  |  | GENERATE_TAGFILE       =  | 
 |  |  | ALLEXTERNALS           = NO | 
 |  |  | EXTERNAL_GROUPS        = YES | 
 |  |  | PERL_PATH              = /usr/bin/perl | 
 |  |  |  | 
 |  |  | #--------------------------------------------------------------------------- | 
 |  |  | # Configuration options related to the dot tool | 
 |  |  | #--------------------------------------------------------------------------- | 
 |  |  | CLASS_DIAGRAMS         = YES | 
 |  |  | MSCGEN_PATH            =  | 
 |  |  | HIDE_UNDOC_RELATIONS   = YES | 
 |  |  | HAVE_DOT               = NO | 
 |  |  | DOT_FONTNAME           = FreeSans | 
 |  |  | DOT_FONTSIZE           = 10 | 
 |  |  | DOT_FONTPATH           =  | 
 |  |  | CLASS_GRAPH            = YES | 
 |  |  | COLLABORATION_GRAPH    = YES | 
 |  |  | GROUP_GRAPHS           = YES | 
 |  |  | UML_LOOK               = NO | 
 |  |  | TEMPLATE_RELATIONS     = NO | 
 |  |  | INCLUDE_GRAPH          = YES | 
 |  |  | INCLUDED_BY_GRAPH      = YES | 
 |  |  | CALL_GRAPH             = NO | 
 |  |  | CALLER_GRAPH           = NO | 
 |  |  | GRAPHICAL_HIERARCHY    = YES | 
 |  |  | DIRECTORY_GRAPH        = YES | 
 |  |  | DOT_IMAGE_FORMAT       = png | 
 |  |  | DOT_PATH               =  | 
 |  |  | DOTFILE_DIRS           =  | 
 |  |  | DOT_GRAPH_MAX_NODES    = 50 | 
 |  |  | MAX_DOT_GRAPH_DEPTH    = 0 | 
 |  |  | DOT_TRANSPARENT        = NO | 
 |  |  | DOT_MULTI_TARGETS      = NO | 
 |  |  | GENERATE_LEGEND        = YES | 
 |  |  | DOT_CLEANUP            = YES | 
 
 |  |  | 
 |  |  |     http://dev.gg.pl/api/pages/botapi.html#rejestracja | 
 |  |  | * ustaw serwer WWW tak, by plik BotGG.php był wykonywany po wejściu na | 
 |  |  |   ustalony przy rejestracji adres | 
 |  |  | * ustaw serwer WWW tak, by plik BotIMI.php był wykonywany po wejściu na | 
 |  |  |   ustalony w IMified.com adres | 
 |  |  | * zmień /sciezka/do/bota w pliku data/update.sh na rzeczywistą, bezwzględną | 
 |  |  |   ścieżkę do katalogu skryptu | 
 |  |  | * wykonuj za pomocą crona polecenie `/sciezka/do/bota/data/update.sh` ok. | 
 |  |  | 
 |  |  | ------- | 
 |  |  |  | 
 |  |  | Jeśli dodajesz/usuwasz moduły lub komendy KONIECZNIE usuń wszystkie pliki | 
 |  |  | z katalogu ./cache - w przeciwnym wypadku polecenia te mogą powodować błędy | 
 |  |  | w działaniu bota! | 
 |  |  | z katalogu ./cache - w przeciwnym wypadku może to powodować błędy | 
 |  |  | w działaniu całego bota! | 
 |  |  |  | 
 |  |  | ------------ | 
 |  |  |  INFORMACJA | 
 |  |  | ------------ | 
 |  |  |  | 
 |  |  | W razie problemów zacznij od zmiany | 
 |  |  |     error_reporting(E_COMPILE_ERROR|E_PARSE); | 
 |  |  | na | 
 
 |  |  | 
 |  |  | Wersję można sprawdzić w pliku ./class/legacy/main.php | 
 |  |  |  | 
 |  |  | =========================== | 
 |  |  |  AKTUALIZACJA Z WERSJI 2.5 | 
 |  |  | =========================== | 
 |  |  |  | 
 |  |  | * nadpisz wszystkie pliki w katalogu ./class (oraz podkatalogach), | 
 |  |  |   za wyjątkiem ./class/config.php | 
 |  |  | * zastąp plik ./data/lotto/pobierz.php | 
 |  |  | * zastąp plik ./data/tv/wp_parse.php | 
 |  |  |  | 
 |  |  | =========================== | 
 |  |  |  AKTUALIZACJA Z WERSJI 2.4 | 
 |  |  | =========================== | 
 
 |  |  | 
 |  |  | <?php | 
 |  |  | /** | 
 |  |  |  * Interfejs do obsługi obrazków przychodzących | 
 |  |  |  */ | 
 |  |  | abstract class BotImage { | 
 |  |  |     /** | 
 |  |  |      * Zmienna przechowująca zasób biblioteki GD2 z obrazkiem | 
 |  |  |      * @var resource $data | 
 |  |  |      */ | 
 |  |  |     protected $data = NULL; | 
 |  |  | 	 | 
 |  |  |     /** | 
 |  |  |      * Funkcja zwracająca zasób GD2 z obrazkiem | 
 |  |  |      * @return resource Zasób GD2 | 
 |  |  |      */ | 
 |  |  |     abstract function getImage(); | 
 |  |  | 	 | 
 |  |  |     /** | 
 |  |  |      * Funkcja zwracająca dane obrazka w formie ciągu bajtów. | 
 |  |  |      * @return string Obrazek | 
 |  |  |      */ | 
 |  |  |     abstract function getImageData(); | 
 |  |  | } | 
 |  |  | ?> | 
 
 |  |  | 
 |  |  |      | 
 |  |  |     function getImageData() { | 
 |  |  |         if($this->data === NULL) { | 
 |  |  |             $push = new BotGGAPI(); | 
 |  |  |             $push = new BotAPIGG(); | 
 |  |  |             $this->data = $push->getImage($this->hash); | 
 |  |  |         } | 
 |  |  |          | 
 
 |  |  | 
 |  |  | class BotMessage { | 
 |  |  |     /** | 
 |  |  |      * Informacje o kliencie | 
 |  |  |      * @var BotUser | 
 |  |  |      * @var BotUser $user | 
 |  |  |      */ | 
 |  |  |     protected $user; | 
 |  |  | 	 | 
 |  |  |     /** | 
 |  |  |      * Informacje o kliencie zgodne z poprzednią wersją Bota (dot. API IMified). | 
 |  |  |      * Najczęściej równe {@link BotMessage::$user} | 
 |  |  |      * @var BotUser | 
 |  |  |      * @var BotUser $userAlt | 
 |  |  |      */ | 
 |  |  |     protected $userAlt; | 
 |  |  |      | 
 |  |  |     /** | 
 |  |  |      * Sesja przypisana do użytkownika i modułu | 
 |  |  |      * @var BotSession | 
 |  |  |      * @var BotSession $session | 
 |  |  |      */ | 
 |  |  |     protected $session; | 
 |  |  |      | 
 |  |  |     /** | 
 |  |  |      * Tekst otrzymany od API - bez zmian | 
 |  |  |      * @var string | 
 |  |  |      * @var string $rawText | 
 |  |  |      */ | 
 |  |  |     protected $rawText; | 
 |  |  |      | 
 |  |  |     /** | 
 |  |  |      * Czysty tekst, tylko znaki ASCII, małe litery, podwójne spacje zamienione na pojedyncze | 
 |  |  |      * @var string | 
 |  |  |      * @var string $text | 
 |  |  |      */ | 
 |  |  |     protected $text; | 
 |  |  |      | 
 |  |  |     /** | 
 |  |  |      * Tablica obrazków (zobacz klasę BotImage) przesłanych do bota przez użytkownika. | 
 |  |  |      * @var array | 
 |  |  |      * Tablica obrazków (zobacz {@link BotImage}) przesłanych do bota przez użytkownika. | 
 |  |  |      * @var array $images | 
 |  |  |      */ | 
 |  |  |     protected $images = array(); | 
 |  |  |      | 
 |  |  |     /** | 
 |  |  |      * Komenda, tylko znaki ASCII, małe litery | 
 |  |  |      * @var string | 
 |  |  |      * @var string $command | 
 |  |  |      */ | 
 |  |  |     private $command; | 
 |  |  |      | 
 |  |  |     /** | 
 |  |  |      * Argumenty polecenia - oryginalne | 
 |  |  |      * @var string | 
 |  |  |      * @var string $args | 
 |  |  |      */ | 
 |  |  |     private $args; | 
 |  |  |      | 
 |  |  |     /** | 
 |  |  |      * Umożliwia dostęp tylko do odczytu do prywanych zmiennych | 
 |  |  |      * @param string $name Nazwa zmiennej | 
 |  |  |      * @return mixed Wartość zmiennej prywatnej | 
 |  |  |      */ | 
 |  |  |     function __get($name) { | 
 |  |  |         return $this->$name; | 
 |  |  |     } | 
 |  |  |      | 
 |  |  |     /** | 
 |  |  |      * Na podstawie nieprzetworzonej wiadomości ({@link BotMessage::$rawText}) | 
 |  |  |      * metoda ustawia wszystkie pola klasy. | 
 |  |  |      * @param string $value Nieprzetworzona wiadomość | 
 |  |  |      */ | 
 |  |  |     function setText($value) { | 
 |  |  |         $this->rawText = $value; | 
 |  |  | 		 | 
 |  |  |         $value = trim($value); | 
 |  |  |         $this->text = funcs::utfToAscii($value); | 
 |  |  |         $this->command = funcs::utfToAscii(trim(strtok($value, " \t\r\n"))); | 
 |  |  |         $this->args = trim(strtok('')); | 
 
 |  |  | 
 |  |  | <?php | 
 |  |  | class BotModuleException extends Exception {} | 
 |  |  |  | 
 |  |  | interface BotModule { | 
 |  |  | } | 
 |  |  | interface BotModule {} | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * Interfejs klasy inicjującej moduł bota | 
 |  |  |  */ | 
 |  |  | interface BotModuleInit { | 
 |  |  |     /** | 
 |  |  |      * Funkcja zwracająca listę obsługiwanych komend. | 
 |  |  |      * Przykład: | 
 |  |  |      * <pre>array( | 
 |  |  |      *   'komenda' => array( | 
 |  |  |      *     array( | 
 |  |  |      *       'file' => 'komenda.php', | 
 |  |  |      *       'class' => 'bot_NAZWAMODULU_module', | 
 |  |  |      *       'method' => 'komenda1', | 
 |  |  |      *       'params' => 'parametr_do_funkcji', | 
 |  |  |      *     ), | 
 |  |  |      *     array( | 
 |  |  |      *       'file' => 'komenda.php', | 
 |  |  |      *       'class' => 'bot_NAZWAMODULU_module', | 
 |  |  |      *       'method' => 'komenda2', | 
 |  |  |      *     ), | 
 |  |  |      *   ), | 
 |  |  |      *   '*' => array( | 
 |  |  |      *     array( | 
 |  |  |      *       'file' => 'test.php', | 
 |  |  |      *       'class' => 'NAZWAMODULU_test', | 
 |  |  |      *       'method' => 'komenda_test', | 
 |  |  |      *     ), | 
 |  |  |      *   ), | 
 |  |  |      * )</pre> | 
 |  |  |      * @return array Lista obsługiwanych komend | 
 |  |  |      */ | 
 |  |  |     function register(); | 
 |  |  | 	 | 
 |  |  |     /** | 
 |  |  |      * Zwraca pomoc dla polecenia lub skróconą listę poleceń | 
 |  |  |      * obsługiwanych przez dany moduł. | 
 |  |  |      * @param string|NULL $params Nazwa komendy | 
 |  |  |      * @return BotMsg Pomoc dla komendy | 
 |  |  |      */ | 
 |  |  |     function help($params = NULL); | 
 |  |  | } | 
 |  |  | ?> | 
 
 |  |  | 
 |  |  | <?php | 
 |  |  | class BotMsgException extends Exception {} | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * Interfejs dla klas przetwarzających wiadomości wychodzące | 
 |  |  |  * do formatu właściwego dla danej sieci. | 
 |  |  |  */ | 
 |  |  | interface BotMsgInterface { | 
 |  |  |     /** | 
 |  |  |      * Konstruktor | 
 |  |  |      * @param BotMsg $msg Wiadomość do przetworzenia | 
 |  |  |      */ | 
 |  |  |     function __construct(BotMsg $msg); | 
 |  |  |     /** | 
 |  |  |      * Zwraca przetworzoną wiadomość | 
 |  |  |      * @return string Wiadomość po przetworzeniu | 
 |  |  |      */ | 
 |  |  |     function __toString(); | 
 |  |  | 	 | 
 |  |  |     /** | 
 |  |  |      * Podaje na wyjście (np. za pomocą echo) wiadomość w formacie | 
 |  |  |      * odpowiednim dla danego API, uwzględniając nagłówki HTTP | 
 |  |  |      * i inne konieczne elementy. | 
 |  |  |      */ | 
 |  |  |     function sendPullResponse(); | 
 |  |  | } | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * Klasa reprezentująca wiadomość wychodzącą. | 
 |  |  |  */ | 
 |  |  | class BotMsg { | 
 |  |  |     private $beautiful = TRUE; | 
 |  |  |     private $parser = NULL; | 
 |  |  | 
 |  |  |     private $raw = ''; | 
 |  |  |      | 
 |  |  |     /** | 
 |  |  |      * Włącza lub wyłącza "upiększanie" konwertowanej do czystego tekstu wiadomości, np.: | 
 |  |  |      * <b>abc</b> zamieniane jest na *abc* | 
 |  |  |      * <h1>efg</h1> przechodzi w = efg = | 
 |  |  |      * Włącza lub wyłącza "upiększanie" konwertowanej | 
 |  |  |      * do czystego tekstu ({@link BotMsg::getText()}) wiadomości, np.: | 
 |  |  |      * | 
 |  |  |      * <b>abc</b> zamieniane jest na \*abc\* | 
 |  |  |      * | 
 |  |  |      * <h1>efg<h1> przechodzi w = efg = | 
 |  |  |      * | 
 |  |  |      * Domyślnie włączone | 
 |  |  |      * @param bool $set Ustawienie "upiększania" | 
 |  |  |      */ | 
 |  |  |     function setBeautiful($set = FALSE) { | 
 |  |  |         if($this->beautiful != $set) { | 
 |  |  |             $this->text = $this->html = $this->parser = NULL; | 
 |  |  |             $this->beautiful = (bool)$set; | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  | 	 | 
 |  |  |     /** | 
 |  |  |      * @deprecated Zastąpiono funkcją {@link BotMsg::setBeautiful()} | 
 |  |  |      */ | 
 |  |  |     function beautifulText($set = FALSE) { | 
 |  |  |         $this->beautiful = (bool)$set; | 
 |  |  |         $this->setBeautiful($set); | 
 |  |  |     } | 
 |  |  |      | 
 |  |  |     /** | 
 |  |  | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |          | 
 |  |  |         return $return; | 
 |  |  |         return trim($return); | 
 |  |  |     } | 
 |  |  |      | 
 |  |  |     private function parseHTMLDOM($dom) { | 
 
 |  |  | 
 |  |  | <?php | 
 |  |  | /** | 
 |  |  |  * Klasa przechowująca dane użytkownika. Całość przypomina mechanizm sesji w PHP. | 
 |  |  |  * Klasa przechowująca dane przekazane przez użytkownika, | 
 |  |  |  * w szczególności jego ustawienia. | 
 |  |  |  */ | 
 |  |  | class BotSession { | 
 |  |  |     private $PDO; | 
 |  |  |      | 
 |  |  |     /** | 
 |  |  |      * Nazwa modułu, którego zmienne klasa przetwarza | 
 |  |  |      * @var string max. 40 znaków | 
 |  |  |      * @var string $class max. 40 znaków | 
 |  |  |      */ | 
 |  |  |     protected $class = ''; | 
 |  |  |     protected $class_empty = TRUE; | 
 |  |  |      | 
 |  |  |     /** | 
 |  |  |      * Pseudo-URL użytkownika. | 
 |  |  |      * @see BotUser | 
 |  |  |      * @var string $user URL użytkownika | 
 |  |  |      */ | 
 |  |  |     private $user; | 
 |  |  |     /** | 
 |  |  |      * Klasa z identyfikatorem użytkownika | 
 |  |  |      * @var BotUser $user_struct | 
 |  |  |      */ | 
 |  |  |     private $user_struct; | 
 |  |  |      | 
 |  |  |     /** | 
 |  |  |      * Inicjuje klasę w zależności od użytkownika | 
 |  |  | 
 |  |  |                 $version = 1; | 
 |  |  |             } | 
 |  |  |              | 
 |  |  |             if($version < 3) { | 
 |  |  |             if($version < 4) { | 
 |  |  |                 $this->PDO->query('DELETE FROM data WHERE class IS NULL AND name=\'user_struct\''); | 
 |  |  |                 $this->PDO->query('INSERT OR REPLACE INTO data (class, name, value) VALUES (\'\', \'_version\', 3)'); | 
 |  |  |                 $version = 3; | 
 |  |  |                 $this->PDO->query('INSERT OR REPLACE INTO data (class, name, value) VALUES (\'\', \'_version\', 4)'); | 
 |  |  |                 $version = 4; | 
 |  |  |             } | 
 |  |  |              | 
 |  |  |             return; | 
 |  |  | 
 |  |  |              | 
 |  |  |             $this->PDO->query( | 
 |  |  |                 'CREATE TABLE data ( | 
 |  |  |                     class VARCHAR(50), | 
 |  |  |                     class VARCHAR(50) NOT NULL DEFAULT \'\', | 
 |  |  |                     name VARCHAR(40) NOT NULL, | 
 |  |  |                     value TEXT NOT NULL, | 
 |  |  |                     PRIMARY KEY ( | 
 |  |  | 
 |  |  |                 )' | 
 |  |  |             ); | 
 |  |  |              | 
 |  |  |             $this->PDO->query('INSERT INTO data (class, name, value) VALUES (\'\', \'_version\', 4)'); | 
 |  |  | 			 | 
 |  |  |             $files = glob(BOT_TOPDIR.'/db/*/'.$this->user_struct['user'].'.ggdb'); | 
 |  |  |             if(!$files) { | 
 |  |  |                 return; | 
 |  |  | 
 |  |  |             $this->PDO->beginTransaction(); | 
 |  |  |             $st = $this->PDO->prepare('INSERT OR REPLACE INTO data (class, name, value) VALUES (?, ?, ?)'); | 
 |  |  |              | 
 |  |  |             $st->execute(array('', '_version', 2)); | 
 |  |  | 			 | 
 |  |  |             foreach($files as $file) { | 
 |  |  |                 $data = unserialize(file_get_contents($file)); | 
 |  |  |                 foreach($data as $name => $value) { | 
 |  |  |                     $st->execute(array($this->class, $name, $value)); | 
 |  |  |                     $st->execute(array($this->class, $name, serialize($value))); | 
 |  |  |                 } | 
 |  |  |             } | 
 |  |  |              | 
 |  |  | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |      | 
 |  |  |     /** | 
 |  |  |      * Ustawia nazwę modułu/klasy, której zmienne będą przetwarzane | 
 |  |  |      * @param string $class Nazwa modułu | 
 |  |  |      */ | 
 |  |  |     function setClass($class) { | 
 |  |  |         $this->class = $class; | 
 |  |  |     } | 
 |  |  | 	 | 
 |  |  |     /** | 
 |  |  |      * Pobiera zmienną modułu o podanej nazwie (getter). | 
 |  |  |      * @param string $name Nazwa zmiennej | 
 |  |  |      * @return mixed Wartość zmiennej lub NULL | 
 |  |  |      */ | 
 |  |  |     function __get($name) { | 
 |  |  |         $this->init(); | 
 |  |  |          | 
 |  |  | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |      | 
 |  |  |     /** | 
 |  |  |      * Ustawia zmienną o podanej nazwie | 
 |  |  |      * @param string $name Nazwa zmiennej | 
 |  |  |      * @param mixed $value Wartość zmiennej | 
 |  |  |      */ | 
 |  |  |     function __set($name, $value) { | 
 |  |  |         $this->init(); | 
 |  |  |          | 
 |  |  | 
 |  |  |         $st->execute(array($this->class, $name, serialize($value))); | 
 |  |  |     } | 
 |  |  |      | 
 |  |  |     /** | 
 |  |  |      * Sprawdza czy podana zmienna została ustawiona. | 
 |  |  |      * @param string $name Nazwa zmiennej | 
 |  |  |      * @return bool Czy zmienna istnieje? | 
 |  |  |      */ | 
 |  |  |     function __isset($name) { | 
 |  |  |         $this->init(); | 
 |  |  |          | 
 |  |  | 
 |  |  |         return ($st[0]>0); | 
 |  |  |     } | 
 |  |  |      | 
 |  |  |     /** | 
 |  |  |      * Usuwa zmienną o podanej nazwie | 
 |  |  |      * @param string $name Nazwa zmiennej | 
 |  |  |      */ | 
 |  |  |     function __unset($name) { | 
 |  |  |         $this->init(); | 
 |  |  |          | 
 |  |  | 
 |  |  |         $st->execute(array($this->class, $name)); | 
 |  |  |     } | 
 |  |  |      | 
 |  |  |     /** | 
 |  |  |      * Zapamiętuje tablicę zmiennych danego modułu | 
 |  |  |      * @param array $array Tablica zmiennych | 
 |  |  |      */ | 
 |  |  |     function push($array) { | 
 |  |  |         $this->PDO->beginTransaction(); | 
 |  |  |         foreach($array as $name => $value) { | 
 |  |  | 
 |  |  |         $this->PDO->commit(); | 
 |  |  |     } | 
 |  |  |      | 
 |  |  |     /** | 
 |  |  |      * Zwraca wszystkie ustawione zmienne danego modułu | 
 |  |  |      * @return array Lista wszystkich zmiennych | 
 |  |  |      */ | 
 |  |  |     function pull() { | 
 |  |  |         $this->init(); | 
 |  |  |          | 
 |  |  | 
 |  |  |          | 
 |  |  |         $return = array(); | 
 |  |  |         foreach($st as $row) { | 
 |  |  |             $return[$row['name']] = $row['value']; | 
 |  |  |             $return[$row['name']] = unserialize($row['value']); | 
 |  |  |         } | 
 |  |  |          | 
 |  |  |         return $return; | 
 |  |  |     } | 
 |  |  |      | 
 |  |  |     function setClass($class) { | 
 |  |  |         $this->class = $class; | 
 |  |  |     } | 
 |  |  | 	 | 
 |  |  |     /** | 
 |  |  |      * Usuwa wszystkie zmienne sesyjne danego modułu. | 
 |  |  |      */ | 
 |  |  |     function truncate() { | 
 |  |  |         $this->init(); | 
 |  |  |          | 
 
 |  |  | 
 |  |  |      * - IMified | 
 |  |  |      * - HTTP | 
 |  |  |      * - Local | 
 |  |  |      * @var string | 
 |  |  |      * @var string $interface | 
 |  |  |      */ | 
 |  |  |     private $interface; | 
 |  |  |      | 
 |  |  |     /** | 
 |  |  |      * Numer lub identyfikator użytkownika | 
 |  |  |      * @var string | 
 |  |  |      * @var string $uid | 
 |  |  |      */ | 
 |  |  |     private $uid; | 
 |  |  |      | 
 |  |  | 
 |  |  |      * - yahoo.imified.com | 
 |  |  |      * - gtalk.imified.com | 
 |  |  |      * - localhost | 
 |  |  |      * @var string | 
 |  |  |      * @var string $network | 
 |  |  |      */ | 
 |  |  |     private $network; | 
 |  |  |      | 
 |  |  |     /** | 
 |  |  |      * Identyfikator/unikalna nazwa bota, do którego skierowano zapytanie. | 
 |  |  |      * Najczęściej numer Gadu-Gadu lub botkey w przypadku IMified.com | 
 |  |  |      * @var string $bot | 
 |  |  |      */ | 
 |  |  |     private $bot; | 
 |  |  |      | 
 |  |  |     /** | 
 |  |  |      * Parametry zapytania. Przy IMified równe zmiennej $_POST['channel'] | 
 |  |  |      * @var string | 
 |  |  |      * @var string $params | 
 |  |  |      */ | 
 |  |  |     private $params; | 
 |  |  |      | 
 |  |  |     /** | 
 |  |  |      * Konstruktor. W argumencie otrzymuje pseudo-URL określający użytkownika i sieć. | 
 |  |  |      * Przykłady: | 
 |  |  |      * - Gadu-Gadu://123456\@gadu-gadu.pl | 
 |  |  |      * - IMified://user\\\@jabber\@jabber.imified.com/BOTKEY?private | 
 |  |  |      * @param string $user URL użytkownika | 
 |  |  |      */ | 
 |  |  |     function __construct($user) { | 
 |  |  |         $data = parse_url($user); | 
 |  |  |          | 
 |  |  | 
 |  |  |         $this->params = @$data['query']; | 
 |  |  |     } | 
 |  |  |      | 
 |  |  |     /** | 
 |  |  |      * Umożliwia dostęp tylko do odczytu do prywanych zmiennych | 
 |  |  |      * @param string $name Nazwa zmiennej | 
 |  |  |      * @return mixed Wartość zmiennej prywatnej | 
 |  |  |      */ | 
 |  |  |     function __get($name) { | 
 |  |  |         return $this->$name; | 
 |  |  |     } | 
 
 |  |  | 
 |  |  | <?php | 
 |  |  | /** | 
 |  |  |  * Klasa obsługująca polskie wyrażenia określające daty | 
 |  |  |  * @todo Potrzebna jest funkcja, które będzie wyciągać datę z początku lub końca danego ciągu. Patrz: {@link tv::parse_date()} | 
 |  |  |  */ | 
 |  |  | class calendar { | 
 |  |  |     /** | 
 |  |  |      * Na podstawie podanej daty zwraca uniksowy znacznik czasu | 
 |  |  |      * @param string $date Data w formacie "naturalnym". Np. jutro, 1 stycznia, piątek | 
 |  |  |      * @return int Uniksowy znacznik czasu. Do użycia w funkcji date() | 
 |  |  |      * @uses funcs::utfToAscii() | 
 |  |  |      * @return int Uniksowy znacznik czasu - liczba sekund od północy 1 stycznia 1970 | 
 |  |  |      * @see http://www.php.net/date | 
 |  |  |      */ | 
 |  |  |     static function parse_date($date) { | 
 |  |  |         $date = funcs::utfToAscii($date); | 
 
 |  |  | 
 |  |  | class BotLegacyEnd extends Exception {} | 
 |  |  |  | 
 |  |  | class funcs { | 
 |  |  |     /** | 
 |  |  |      * Przerywa dalsze wykonywanie modułu i wysyła odpowiedź do klienta | 
 |  |  |      * @deprecated Przestarzałe wraz z wprowadzeniem nowego API. | 
 |  |  |      *  Metoda może zostać usunięta bez ostrzeżenia! | 
 |  |  |      */ | 
 |  |  |     static function end() { | 
 |  |  |         throw new BotLegacyEnd(); | 
 |  |  |     } | 
 |  |  |      | 
 |  |  |     /** | 
 |  |  |      * Funkcja usuwa "ogonki" (transliteracja), podwójne spacje i odstępy | 
 |  |  |      * z podanego w parametrze ciągu znaków oraz zamienia wszystkie litery na małe | 
 |  |  |      * @param string $utf Ciąg znaków w UTF-8 | 
 |  |  |      * @returns string Ciąg po przetworzeniu | 
 |  |  |      */ | 
 |  |  |     static function utfToAscii($utf) { | 
 |  |  |         $utf = trim(str_replace('  ', ' ', $utf)); | 
 |  |  |         return strtolower(iconv('utf-8', 'ascii//TRANSLIT', trim($utf))); | 
 |  |  |         return strtolower(iconv('utf-8', 'ascii//TRANSLIT', $utf)); | 
 |  |  |     } | 
 |  |  | } | 
 |  |  | ?> | 
 
 |  |  | 
 |  |  |                 // Ignore  < ? php  and  ? >  added above | 
 |  |  |                 if($token[0] == T_OPEN_TAG OR $token[0] == T_CLOSE_TAG) continue; | 
 |  |  |                 // String/int element within an array | 
 |  |  |                 if($token[0] == T_CONSTANT_ENCAPSED_STRING || $token[0] == T_LNUMBER) { | 
 |  |  |                 if($token[0] == T_CONSTANT_ENCAPSED_STRING) { | 
 |  |  |                     $element = substr($token[1], 1, -1); | 
 |  |  |                 } | 
 |  |  |                 if($token[0] == T_LNUMBER) { | 
 |  |  |                     $element = $token[1]; | 
 |  |  |                 } | 
 |  |  |             } | 
 |  |  |             // Nested array | 
 |  |  | 
 |  |  |             } | 
 |  |  |             // End of nested array | 
 |  |  |             elseif($token == ']') { | 
 |  |  |                 // Put elements into the lastest array | 
 |  |  |                 // Put elements into the latest array | 
 |  |  |                 if($element !== NULL && $element !== FALSE) { | 
 |  |  |                     end($stack); | 
 |  |  |                     $stack[key($stack)][] = $element; | 
 |  |  | 
 |  |  |             } | 
 |  |  |             // Elements separator | 
 |  |  |             elseif($token == ',') { | 
 |  |  |                 // Put elements into the lastest array (]] check) | 
 |  |  |                 // Put elements into the latest array (]] check) | 
 |  |  |                 if($element !== FALSE) { | 
 |  |  |                     end($stack); | 
 |  |  |                     $stack[key($stack)][] = $element; | 
 |  |  | 
 |  |  |             } | 
 |  |  |             else | 
 |  |  |             { | 
 |  |  |                 return array(); | 
 |  |  |                 return FALSE; | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |          | 
 |  |  |         return $stack[0][0]; | 
 |  |  |         if(isset($stack[0][0])) { | 
 |  |  |             return $stack[0][0]; | 
 |  |  |         } else { | 
 |  |  |             return NULL; | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  | } | 
 |  |  | ?> | 
 
 |  |  | 
 |  |  | <?php | 
 |  |  | class main { | 
 |  |  |     const VERSION = '2.5'; | 
 |  |  |     const VERSION_NUM = '2.5'; | 
 |  |  |     /** | 
 |  |  |      * Wersja bota w formacie: <i>X.Y TYPE</i>, np. <i>2.0 Beta</i> | 
 |  |  |      */ | 
 |  |  |     const VERSION = '2.6'; | 
 |  |  |     /** | 
 |  |  |      * Wersja bota, tylko część numeryczna (X.Y), np. <i>2.0</i> | 
 |  |  |      */ | 
 |  |  |     const VERSION_NUM = '2.6'; | 
 |  |  | } | 
 |  |  | ?> | 
 
 |  |  | 
 |  |  | <?php | 
 |  |  | interface module { | 
 |  |  |     static function register_cmd(); | 
 |  |  |     // Returns: | 
 |  |  |     // Zwraca: | 
 |  |  |     // array( | 
 |  |  |     //   'CMD1_NAME' => 'FUNCTION_INSIDE_CLASS', | 
 |  |  |     //   'CMD2_NAME' => 'FUNCTION_INSIDE_CLASS', | 
 |  |  |     //   'KOMENDA1' => 'METODA_OBSLUGUJACA_KOMENDE1', | 
 |  |  |     //   'KOMENDA2' => 'METODA_OBSLUGUJACA_KOMENDE2', | 
 |  |  |     //   ... | 
 |  |  |     // ) | 
 |  |  |      | 
 |  |  |     static function help($cmd=NULL); | 
 |  |  |     // Return help content about command $cmd to GGapi::put*() functions | 
 |  |  |     //    if $cmd is NULL return help content for all commands | 
 |  |  |     // Zwraca pomoc dotyczącą komendy z użyciem funkcji GGapi::put*() | 
 |  |  |     // Jeśli $cmd === NULL, zwraca skróconą listę poleceń modułu | 
 |  |  |      | 
 |  |  |     // static function FUNCTION_INSIDE_CLASS(CMD_NAME, REST_OF_PLAINTEXT) | 
 |  |  |     //    REST_OF_PLAINTEXT is raw (non trimmed etc.) part after command name, without leading space | 
 |  |  |     // static function METODA_OBSLUGUJACA_KOMENDE(NAZWA_KOMENDY, ARGUMENTY) | 
 |  |  |     //    ARGUMENTY to wszystko poza nazwą komendy, przekazane w taki sposób, | 
 |  |  |     //    w jaki zostały otrzymane od użytkownika | 
 |  |  | } | 
 |  |  | ?> | 
 
 |  |  | 
 |  |  |     throw new ErrorException($errstr, 0, $errno, $errfile, $errline); | 
 |  |  | } | 
 |  |  |  | 
 |  |  | error_reporting(E_COMPILE_ERROR|E_PARSE); | 
 |  |  | if(!defined('PHPUNIT')) { | 
 |  |  |     error_reporting(E_COMPILE_ERROR|E_PARSE); | 
 |  |  |     set_error_handler('errorToException', E_ALL & ~E_NOTICE); | 
 |  |  | } | 
 |  |  |  | 
 |  |  | setlocale(LC_CTYPE, 'pl_PL.utf8', 'pl_PL', 'polish', 'plk'); | 
 |  |  | mb_internal_encoding('UTF-8'); | 
 |  |  | libxml_use_internal_errors(); | 
 |  |  | spl_autoload_register('botAutoload'); | 
 |  |  | set_error_handler('errorToException', E_ALL & ~E_NOTICE); | 
 |  |  | ?> | 
 
| New file | 
 |  |  | 
 |  |  | <phpunit bootstrap="tests/autoload.php"> | 
 |  |  |   <php> | 
 |  |  |     <const name="PHPUNIT" value="true" /> | 
 |  |  |   </php> | 
 |  |  |   <testsuites> | 
 |  |  |     <testsuite name="Core Test Suite"> | 
 |  |  |       <directory suffix="Test.php">tests/Core</directory> | 
 |  |  |     </testsuite> | 
 |  |  |   </testsuites> | 
 |  |  | </phpunit> | 
 
| New file | 
 |  |  | 
 |  |  | <?php | 
 |  |  | class BotMessageTest extends PHPUnit_Framework_TestCase { | 
 |  |  |     function testAppend() { | 
 |  |  |         $input = '   ąęß  śćżń  óó '; | 
 |  |  |         $message = new BotMessage(); | 
 |  |  |         $message->setText($input); | 
 |  |  | 		 | 
 |  |  |         $this->assertEquals($input, $message->rawText); | 
 |  |  |         $this->assertEquals('aess sczn oo', $message->text); | 
 |  |  |         $this->assertEquals('aess', $message->command); | 
 |  |  |         $this->assertEquals('śćżń  óó', $message->args); | 
 |  |  |     } | 
 |  |  | } | 
 
| New file | 
 |  |  | 
 |  |  | <?php | 
 |  |  | class BotMsgTest extends PHPUnit_Framework_TestCase { | 
 |  |  |     function testAppend() { | 
 |  |  |         $text = ''; | 
 |  |  |  | 
 |  |  |         $substring = 'abc'; | 
 |  |  |         $msg = new BotMsg($substring); | 
 |  |  |         $text .= $substring; | 
 |  |  | 		 | 
 |  |  |         $substring = 'cba'; | 
 |  |  |         $msg->a($substring); | 
 |  |  |         $text .= $substring; | 
 |  |  | 		 | 
 |  |  |         $substring = 'cba'; | 
 |  |  |         $msg->append($substring); | 
 |  |  |         $text .= $substring; | 
 |  |  |  | 
 |  |  |         $this->assertEquals($text, $msg->getRaw()); | 
 |  |  |     } | 
 |  |  | 	 | 
 |  |  |     function testBeautifilText() { | 
 |  |  |         $msg = new BotMsg('<h1>Test</h1><p><u><i>This.</i></u></p><p><b>That!</b></p>'); | 
 |  |  |         $expect = '= Test ='."\n" | 
 |  |  |             .'_/This./_'."\n\n" | 
 |  |  |             .'*That!*'; | 
 |  |  |         $msg->setBeautiful(TRUE); | 
 |  |  |         $this->assertEquals($expect, $msg->getText()); | 
 |  |  | 		 | 
 |  |  |         $expect = 'Test'."\n" | 
 |  |  |             .'This.'."\n\n" | 
 |  |  |             .'That!'; | 
 |  |  |         $msg->setBeautiful(FALSE); | 
 |  |  |         $this->assertEquals($expect, $msg->getText()); | 
 |  |  | 		 | 
 |  |  |     } | 
 |  |  | 	 | 
 |  |  |     function testGetText() { | 
 |  |  |         $msg = new BotMsg('<h2>Test</h2>'."\n" | 
 |  |  |             .'<h3>Test h3</h3>'."\n" | 
 |  |  |             .'<p><a href="http://jacekk.info">http://jacekk.info</a><br />'."\n" | 
 |  |  |             .'<a href="http://jacekk.info">Jacekk.info</a></p>'); | 
 |  |  |         $expect = '== Test =='."\n" | 
 |  |  |             .'=== Test h3 ==='."\n" | 
 |  |  |             .'http://jacekk.info'."\n" | 
 |  |  |             .'Jacekk.info (http://jacekk.info)'; | 
 |  |  |         $this->assertEquals($expect, $msg->getText()); | 
 |  |  | 		 | 
 |  |  |         $msg = new BotMsg('<table>'."\n" | 
 |  |  |             .'<tr><th>Header 1</th> <th>Header 2</th></tr>'."\n" | 
 |  |  |             .'<tr><td>Cell 1</td> <td>Cell 2<img src="" /></td></tr>'."\n" | 
 |  |  |             .'</table>'); | 
 |  |  |         $expect = '*Header 1*     *Header 2*'."\n" | 
 |  |  |             .'Cell 1     Cell 2'; | 
 |  |  |         $this->assertEquals($expect, $msg->getText()); | 
 |  |  | 		 | 
 |  |  |         $msg = new BotMsg('<h3>Test h3</h3>abc<p>Test</p>'); | 
 |  |  |         $expect = '=== Test h3 ==='."\n" | 
 |  |  |             .'abc'."\n\n" | 
 |  |  |             .'Test'; | 
 |  |  |         $this->assertEquals($expect, $msg->getText()); | 
 |  |  |     } | 
 |  |  | 	 | 
 |  |  |     function testGetHTML() { | 
 |  |  |         $msg = new BotMsg('<h1>Test</h1>'."\n" | 
 |  |  |             .'<p><u><i>This.</i></u></p>'."\n" | 
 |  |  |             .'<p><b color="#fff">That!</b></p>'."\n" | 
 |  |  |             .'<p><a>http://jacekk.info</a></p>'); | 
 |  |  |         $expect = '<h1>Test</h1>'."\n" | 
 |  |  |             .'<p><u><i>This.</i></u></p>'."\n" | 
 |  |  |             .'<p><b style="color:#fff;">That!</b></p>'."\n" | 
 |  |  |             .'<p><a href="http://jacekk.info">http://jacekk.info</a></p>'; | 
 |  |  | 		 | 
 |  |  |         $this->assertEquals($expect, $msg->getHTML()); | 
 |  |  |         $this->assertEquals($expect, (string)$msg); | 
 |  |  |     } | 
 |  |  | 	 | 
 |  |  |     function testHTMLError() { | 
 |  |  |         $oldhandler = set_error_handler('errorToException'); | 
 |  |  | 		 | 
 |  |  |         $msg = new BotMsg('<![CDATA[ <p></p> ]]>'); | 
 |  |  |         $msg->getHTML(); | 
 |  |  | 		 | 
 |  |  |         set_error_handler($oldhandler); | 
 |  |  |     } | 
 |  |  | 	 | 
 |  |  |     function testSleep() { | 
 |  |  |         $msg = new BotMsg('<h1>Test</h1><p><u><i>This.</i></u></p><p><b>That!</b></p>'); | 
 |  |  |         $raw = $msg->getRaw(); | 
 |  |  |         $text = $msg->getText(); | 
 |  |  |         $html = $msg->getHTML(); | 
 |  |  | 		 | 
 |  |  |         $serialized = serialize($msg); | 
 |  |  |         $msg = unserialize($serialized); | 
 |  |  | 		 | 
 |  |  |         $this->assertEquals($raw, $msg->getRaw()); | 
 |  |  |         $this->assertEquals($text, $msg->getText()); | 
 |  |  |         $this->assertEquals($html, $msg->getHTML()); | 
 |  |  |     } | 
 |  |  | } | 
 
| New file | 
 |  |  | 
 |  |  | <?php | 
 |  |  | class BotSessionTest extends PHPUnit_Framework_TestCase { | 
 |  |  |     function testSessionFolder() { | 
 |  |  |         $dbFolder = dirname(__FILE__).'/../../database'; | 
 |  |  | 		 | 
 |  |  |         $this->assertTrue(is_writable($dbFolder)); | 
 |  |  |         $this->assertTrue(count(glob($dbFolder.'/*.sqlite')) == 0); | 
 |  |  |     } | 
 |  |  | 	 | 
 |  |  |     /** | 
 |  |  |      * @depends testSessionFolder | 
 |  |  |      */ | 
 |  |  |     function testPullEmpty() { | 
 |  |  |         $dbFolder = dirname(__FILE__).'/../../database'; | 
 |  |  | 		 | 
 |  |  |         $session = new BotSession('test://user1@test'); | 
 |  |  |         $session->setClass('test'); | 
 |  |  | 		 | 
 |  |  |         $this->assertEquals(array(), $session->pull()); | 
 |  |  |         $this->assertTrue(count(glob($dbFolder.'/*.sqlite')) == 1); | 
 |  |  |     } | 
 |  |  | 	 | 
 |  |  |     /** | 
 |  |  |      * @depends testPullEmpty | 
 |  |  |      * @expectedException Exception | 
 |  |  |      */ | 
 |  |  |     function testSetClass() { | 
 |  |  |         $session = new BotSession('test://user1'); | 
 |  |  |         $session->pull(); | 
 |  |  |     } | 
 |  |  | 	 | 
 |  |  |     /** | 
 |  |  |      * @depends testPullEmpty | 
 |  |  |      */ | 
 |  |  |     function testLegacyImport() { | 
 |  |  |         $dbFolder = dirname(__FILE__).'/../../database'; | 
 |  |  |         $oldDbFolder = $dbFolder = dirname(__FILE__).'/../../db'; | 
 |  |  | 		 | 
 |  |  |         $data = array('test' => true, 'other' => 'yes, sir!'); | 
 |  |  |         $data_serialized = serialize($data); | 
 |  |  | 		 | 
 |  |  |         $this->assertTrue(mkdir($oldDbFolder)); | 
 |  |  |         $this->assertTrue(is_writable($oldDbFolder)); | 
 |  |  |         $this->assertTrue(mkdir($oldDbFolder.'/test')); | 
 |  |  | 		 | 
 |  |  |         $filename = $oldDbFolder.'/test/testUser.ggdb'; | 
 |  |  |         $this->assertEquals(strlen($data_serialized), file_put_contents($filename, $data_serialized)); | 
 |  |  |         $this->assertEquals($data_serialized, file_get_contents($filename)); | 
 |  |  | 		 | 
 |  |  |         $session = new BotSession('test://testUser@test'); | 
 |  |  |         $session->setClass('test'); | 
 |  |  | 		 | 
 |  |  |         $this->assertTrue(isset($session->test)); | 
 |  |  |         $this->assertEquals($data, $session->pull()); | 
 |  |  | 		 | 
 |  |  |         $this->assertFalse(file_exists($filename)); | 
 |  |  |         $this->assertTrue(rmdir($oldDbFolder.'/test')); | 
 |  |  |         $this->assertTrue(rmdir($oldDbFolder)); | 
 |  |  |     } | 
 |  |  | 	 | 
 |  |  |     /** | 
 |  |  |      * @depends testPullEmpty | 
 |  |  |      */ | 
 |  |  |     function testManualExample() { | 
 |  |  |         $session = new BotSession('test://user1@test'); | 
 |  |  |         $session->setClass('test'); | 
 |  |  | 		 | 
 |  |  |         // Ustawienie pojedynczej wartości | 
 |  |  |         $session->zmienna = 'To jest test'; | 
 |  |  |         $this->assertTrue(isset($session->zmienna)); | 
 |  |  |         $this->assertEquals('To jest test', $session->zmienna); | 
 |  |  | 		 | 
 |  |  |         // Usunięcie pojedynczej wartości | 
 |  |  |         unset($session->zmienna); | 
 |  |  |         $this->assertFalse(isset($session->zmienna)); | 
 |  |  |         $this->assertEquals(NULL, $session->zmienna); | 
 |  |  | 		 | 
 |  |  |         // Ustawienie pojedynczej wartości ponownie | 
 |  |  |         $session->zmienna = 'To jest test'; | 
 |  |  |         $this->assertTrue(isset($session->zmienna)); | 
 |  |  |         $this->assertEquals('To jest test', $session->zmienna); | 
 |  |  | 		 | 
 |  |  |         // Usunięcie wszystkich danych | 
 |  |  |         $session->truncate(); | 
 |  |  |         $this->assertFalse(isset($session->zmienna)); | 
 |  |  |         $this->assertEquals(NULL, $session->zmienna); | 
 |  |  |         $this->assertEquals(array(), $session->pull()); | 
 |  |  |  | 
 |  |  |         // Dopisanie (nadpisanie) danych | 
 |  |  |         $array = array( | 
 |  |  |             'zmienna' => 'To jest test2', | 
 |  |  |             'zmienna2' => new DateTime('2012-01-10') | 
 |  |  |         ); | 
 |  |  |         $session->push($array); | 
 |  |  |  | 
 |  |  |         $this->assertEquals('To jest test2', $session->zmienna); | 
 |  |  |         $this->assertEquals($array, $session->pull()); | 
 |  |  | 		 | 
 |  |  |         // push() nie usuwa istniejących danych | 
 |  |  |         $session->zmienna3 = '333'; | 
 |  |  |         $session->push($array); | 
 |  |  |         $this->assertNotEquals($array, $session->pull()); | 
 |  |  | 		 | 
 |  |  |         unset($this->session); | 
 |  |  |     } | 
 |  |  | 	 | 
 |  |  |     /** | 
 |  |  |      * @depends testManualExample | 
 |  |  |      */ | 
 |  |  |     function testManualExample2() { | 
 |  |  |         $session = new BotSession('test://user1@test'); | 
 |  |  |         $session->setClass('test'); | 
 |  |  | 		 | 
 |  |  |         $array = array( | 
 |  |  |             'zmienna' => 'To jest test2', | 
 |  |  |             'zmienna2' => new DateTime('2012-01-10'), | 
 |  |  |             'zmienna3' => '333' | 
 |  |  |         ); | 
 |  |  | 		 | 
 |  |  |         $this->assertEquals($array, $session->pull()); | 
 |  |  | 		 | 
 |  |  | 		 | 
 |  |  |         $session->setClass('test2'); | 
 |  |  |         $this->assertEquals(array(), $session->pull()); | 
 |  |  |     } | 
 |  |  | 	 | 
 |  |  |     /** | 
 |  |  |      * @depends testManualExample2 | 
 |  |  |      */ | 
 |  |  |     function testCleanup() { | 
 |  |  |         $dbFolder = dirname(__FILE__).'/../../database'; | 
 |  |  |         foreach(glob($dbFolder.'/*.sqlite') as $file) { | 
 |  |  |             unlink($file); | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  | } | 
 
| New file | 
 |  |  | 
 |  |  | <?php | 
 |  |  | class JSArrayTest extends PHPUnit_Framework_TestCase { | 
 |  |  |     public function testEmptyString() { | 
 |  |  |         $result = jsarray::parse(''); | 
 |  |  |         $this->assertSame(NULL, $result); | 
 |  |  |     } | 
 |  |  | 	 | 
 |  |  |     public function testEmptyArray() { | 
 |  |  |         $result = jsarray::parse('[]'); | 
 |  |  |         $this->assertEquals(array(), $result); | 
 |  |  |     } | 
 |  |  | 	 | 
 |  |  |     public function testNestedArrays() {  | 
 |  |  |         $array = array( | 
 |  |  |             array(1, 2, array(), 5, array(6, array(7, 8))), | 
 |  |  |             array(9), | 
 |  |  |             '10' | 
 |  |  |         ); | 
 |  |  |         $array_js = json_encode($array); | 
 |  |  |         $array_decoded = jsarray::parse($array_js); | 
 |  |  | 		 | 
 |  |  |         $this->assertEquals($array, $array_decoded); | 
 |  |  |     } | 
 |  |  | 	 | 
 |  |  |     public function testInvalid() { | 
 |  |  |         $result = jsarray::parse('()'); | 
 |  |  |         $this->assertSame(FALSE, $result); | 
 |  |  |     } | 
 |  |  | } | 
 
| New file | 
 |  |  | 
 |  |  | <?php | 
 |  |  | require_once(dirname(__FILE__).'/../class/std.php'); |