├── .github
└── workflows
│ ├── release.yml
│ └── test.yml
├── .gitignore
├── LICENSE.txt
├── Makefile
├── README.md
├── app
├── .htaccess
├── config.sample.php
├── config_read_from_env.php
├── db
│ └── 0_initialize.sql
├── locale
│ ├── en_US.UTF-8
│ │ └── LC_MESSAGES
│ │ │ ├── messages.mo
│ │ │ └── messages.po
│ └── ja_JP.UTF-8
│ │ └── LC_MESSAGES
│ │ ├── messages.mo
│ │ └── messages.po
├── src
│ ├── App.php
│ ├── Cli
│ │ └── Controller
│ │ │ └── Cron
│ │ │ └── EntriesController.php
│ ├── Config.php
│ ├── Exception
│ │ ├── PseudoExit.php
│ │ └── RedirectExit.php
│ ├── Lib
│ │ ├── CaptchaImage.php
│ │ ├── ThumbnailImageMaker.php
│ │ ├── WordTag.php
│ │ └── fonts
│ │ │ └── ume-ugo4.ttf
│ ├── Model
│ │ ├── ArrayIterableTrait.php
│ │ ├── Blog.php
│ │ ├── BlogPluginsModel.php
│ │ ├── BlogSettingsModel.php
│ │ ├── BlogTemplatesModel.php
│ │ ├── BlogsModel.php
│ │ ├── CategoriesModel.php
│ │ ├── CommentsModel.php
│ │ ├── Email.php
│ │ ├── EmailLoginToken.php
│ │ ├── EmailLoginTokenModel.php
│ │ ├── EmailLoginTokenService.php
│ │ ├── EntriesModel.php
│ │ ├── EntryCategoriesModel.php
│ │ ├── EntryTagsModel.php
│ │ ├── Fc2TemplatesModel.php
│ │ ├── FilesModel.php
│ │ ├── Model.php
│ │ ├── PDOConnection.php
│ │ ├── PDOQuery.php
│ │ ├── PasswordResetToken.php
│ │ ├── PasswordResetTokenModel.php
│ │ ├── PasswordResetTokenService.php
│ │ ├── PluginsModel.php
│ │ ├── QueryTrait.php
│ │ ├── SystemUpdateModel.php
│ │ ├── TagsModel.php
│ │ ├── User.php
│ │ ├── UsersModel.php
│ │ └── Validate.php
│ ├── Repo
│ │ ├── MailerInterface.php
│ │ ├── SendmailMailer.php
│ │ └── StdErrOutputMailer.php
│ ├── Service
│ │ ├── AccessBlock.php
│ │ ├── BlogService.php
│ │ ├── MailService.php
│ │ ├── TwigService.php
│ │ └── UserService.php
│ ├── Util
│ │ ├── I18n.php
│ │ ├── Log.php
│ │ ├── PhpCodeLinter.php
│ │ ├── StringCaseConverter.php
│ │ └── Twig
│ │ │ ├── GetTextHelper.php
│ │ │ └── HtmlHelper.php
│ ├── Web
│ │ ├── Controller
│ │ │ ├── Admin
│ │ │ │ ├── AdminController.php
│ │ │ │ ├── BlogPluginsController.php
│ │ │ │ ├── BlogSettingsController.php
│ │ │ │ ├── BlogTemplatesController.php
│ │ │ │ ├── BlogsController.php
│ │ │ │ ├── CategoriesController.php
│ │ │ │ ├── CommentsController.php
│ │ │ │ ├── CommonController.php
│ │ │ │ ├── EntriesController.php
│ │ │ │ ├── FilesController.php
│ │ │ │ ├── PasswordResetController.php
│ │ │ │ ├── SessionController.php
│ │ │ │ ├── SystemUpdateController.php
│ │ │ │ ├── TagsController.php
│ │ │ │ └── UsersController.php
│ │ │ ├── Controller.php
│ │ │ └── User
│ │ │ │ ├── BlogsController.php
│ │ │ │ ├── CommonController.php
│ │ │ │ ├── EntriesController.php
│ │ │ │ └── UserController.php
│ │ ├── Cookie.php
│ │ ├── Fc2BlogTemplate.php
│ │ ├── Html.php
│ │ ├── Request.php
│ │ ├── Router
│ │ │ └── Router.php
│ │ └── Session.php
│ ├── config
│ │ ├── fc2_default_plugin.php
│ │ └── fc2_template.php
│ └── include
│ │ ├── common_functions.php
│ │ └── index_include.php
├── temp
│ └── .gitkeep
├── templates
│ ├── default
│ │ ├── fc2_default_css_pc.css
│ │ ├── fc2_default_css_sp.css
│ │ ├── fc2_default_template_pc.php
│ │ └── fc2_default_template_sp.php
│ └── skeleton
│ │ ├── fc2_skeleton_css_pc.css
│ │ ├── fc2_skeleton_css_sp.css
│ │ ├── fc2_skeleton_template_pc.php
│ │ └── fc2_skeleton_template_sp.php
└── twig_templates
│ ├── admin
│ ├── blog_plugins
│ │ ├── create.twig
│ │ ├── edit.twig
│ │ ├── edit_sp.twig
│ │ ├── form_js.twig
│ │ ├── index.twig
│ │ ├── index_sp.twig
│ │ ├── plugin_search.twig
│ │ ├── plugin_search_sp.twig
│ │ └── register.twig
│ ├── blog_settings
│ │ ├── comment_edit.twig
│ │ ├── comment_edit_sp.twig
│ │ ├── entry_edit.twig
│ │ ├── entry_edit_sp.twig
│ │ ├── etc_edit.twig
│ │ ├── etc_edit_sp.twig
│ │ ├── tab.twig
│ │ └── tab_sp.twig
│ ├── blog_templates
│ │ ├── create.twig
│ │ ├── edit.twig
│ │ ├── fc2_index.twig
│ │ ├── fc2_index_sp.twig
│ │ ├── fc2_view.twig
│ │ ├── fc2_view_sp.twig
│ │ ├── form_js.twig
│ │ ├── index.twig
│ │ └── index_sp.twig
│ ├── blogs
│ │ ├── create.twig
│ │ ├── create_sp.twig
│ │ ├── delete.twig
│ │ ├── delete_sp.twig
│ │ ├── edit.twig
│ │ ├── edit_sp.twig
│ │ ├── index.twig
│ │ └── index_sp.twig
│ ├── categories
│ │ ├── ajax_add.twig
│ │ ├── ajax_add_sp.twig
│ │ ├── create.twig
│ │ ├── create_sp.twig
│ │ ├── edit.twig
│ │ └── edit_sp.twig
│ ├── comments
│ │ ├── ajax_reply.twig
│ │ ├── index.twig
│ │ ├── index_sp.twig
│ │ ├── reply.twig
│ │ └── reply_sp.twig
│ ├── common
│ │ ├── error404.twig
│ │ ├── error404_sp.twig
│ │ ├── install.twig
│ │ ├── install_user.twig
│ │ ├── installed.twig
│ │ ├── json.twig
│ │ ├── notice.twig
│ │ ├── notice_sp.twig
│ │ ├── paging.twig
│ │ └── paging_sp.twig
│ ├── email_login
│ │ ├── expired.twig
│ │ ├── mail_sending_error.twig
│ │ └── requested.twig
│ ├── entries
│ │ ├── ajax_media_load.twig
│ │ ├── ajax_media_load_sp.twig
│ │ ├── create.twig
│ │ ├── create_sp.twig
│ │ ├── edit.twig
│ │ ├── edit_sp.twig
│ │ ├── editor_js.twig
│ │ ├── editor_js_sp.twig
│ │ ├── form.twig
│ │ ├── form_sp.twig
│ │ ├── index.twig
│ │ └── index_sp.twig
│ ├── files
│ │ ├── ajax_index.twig
│ │ ├── edit.twig
│ │ ├── edit_sp.twig
│ │ ├── upload.twig
│ │ └── upload_sp.twig
│ ├── flagments
│ │ ├── flash_message.twig
│ │ └── flash_message_sp.twig
│ ├── layouts
│ │ ├── default.twig
│ │ ├── default_nomenu.twig
│ │ └── default_sp.twig
│ ├── password_reset
│ │ ├── complete.twig
│ │ ├── expired.twig
│ │ ├── mail_sending_error.twig
│ │ ├── request_form.twig
│ │ ├── requested.twig
│ │ └── reset_form.twig
│ ├── session
│ │ ├── login.twig
│ │ └── login_sp.twig
│ ├── system_update
│ │ └── index.twig
│ ├── tags
│ │ ├── edit.twig
│ │ ├── edit_sp.twig
│ │ ├── index.twig
│ │ └── index_sp.twig
│ └── users
│ │ ├── edit.twig
│ │ ├── edit_sp.twig
│ │ ├── index.twig
│ │ ├── tab.twig
│ │ ├── tab_sp.twig
│ │ ├── withdrawal.twig
│ │ └── withdrawal_sp.twig
│ ├── fragment
│ ├── checkbox.twig
│ ├── file.twig
│ ├── hidden.twig
│ ├── li.twig
│ ├── password.twig
│ ├── radio.twig
│ ├── radio_label.twig
│ ├── select.twig
│ ├── text.twig
│ ├── textarea.twig
│ ├── ul.twig
│ └── undefined.twig
│ ├── mail
│ ├── email_login.twig
│ └── password_recovery_request.twig
│ └── user
│ ├── common
│ ├── error400.twig
│ ├── error400_sp.twig
│ ├── error403.twig
│ ├── error403_sp.twig
│ ├── error404.twig
│ ├── error404_sp.twig
│ ├── error500.twig
│ └── error500_sp.twig
│ ├── entries
│ ├── blog_password.twig
│ ├── blog_password_sp.twig
│ ├── edit_comment_form.twig
│ ├── edit_comment_form_sp.twig
│ ├── register_comment_form.twig
│ ├── register_comment_form_sp.twig
│ └── syntax_error.twig
│ └── layouts
│ ├── default.twig
│ └── default_sp.twig
├── composer.json
├── composer.lock
├── dist_zip
├── .gitignore
├── Makefile
├── README.md
├── installer
│ └── fc2blog_installer.php
└── test_vm
│ ├── 001-blog.conf
│ ├── Dockerfile
│ ├── Makefile
│ ├── config.php
│ └── startup.sh
├── docker-compose.yml
├── docker
├── apache
│ ├── Dockerfile
│ ├── etc
│ │ └── apache2
│ │ │ ├── apache2.conf
│ │ │ └── sites-available
│ │ │ └── 001-blog.conf
│ └── usr
│ │ └── local
│ │ └── etc
│ │ └── php
│ │ └── conf.d
│ │ ├── docker-php-ext-xdebug-debug-enable.ini
│ │ └── php-error-settings.ini
└── mysqld
│ ├── Dockerfile
│ └── mysqld.cnf
├── e2e_test
├── .env.sample
├── .gitignore
├── README.md
├── babel.config.js
├── jest.config.js
├── jest.setup.js
├── package-lock.json
├── package.json
├── serial_execute_tests
│ ├── admin_entry_create_delete.test.ts
│ └── installer.test.ts
├── ss
│ └── .gitkeep
└── tests
│ ├── admin_crawl.test.ts
│ ├── admin_file.test.ts
│ ├── admin_installer.test.ts
│ ├── blog_archive.test.ts
│ ├── blog_crawl.test.ts
│ ├── blog_crawl_sp.test.ts
│ ├── helper.ts
│ ├── notfound.test.ts
│ ├── open_base_url.test.ts
│ ├── password_required_form.test.ts
│ ├── test.png
│ └── test.test.ts
├── package-lock.json
├── package.json
├── phpunit.xml
├── public
├── .htaccess
├── assets
│ ├── admin
│ │ ├── css
│ │ │ ├── admin-fc2.css
│ │ │ └── sp
│ │ │ │ ├── admin-fc2-sp.css
│ │ │ │ ├── category_sp.css
│ │ │ │ └── entry_sp.css
│ │ ├── img
│ │ │ ├── admin_icon2_02.png
│ │ │ ├── admin_icon3.png
│ │ │ ├── handle.png
│ │ │ └── sp
│ │ │ │ ├── sp_blog_btn_icon.png
│ │ │ │ ├── sp_blog_btn_icon@2x.png
│ │ │ │ ├── sp_blog_detail_bg.png
│ │ │ │ ├── sp_blog_detail_bg@2x.png
│ │ │ │ ├── sp_blog_sidemenu_bg.png
│ │ │ │ └── sp_blog_sidemenu_bg@2x.png
│ │ └── js
│ │ │ ├── elrte
│ │ │ ├── Changelog
│ │ │ ├── README
│ │ │ ├── css
│ │ │ │ ├── elrte-inner.css
│ │ │ │ ├── elrte.full.css
│ │ │ │ ├── elrte.min.css
│ │ │ │ └── smoothness
│ │ │ │ │ ├── images
│ │ │ │ │ ├── ui-bg_flat_0_aaaaaa_40x100.png
│ │ │ │ │ ├── ui-bg_flat_75_ffffff_40x100.png
│ │ │ │ │ ├── ui-bg_glass_55_fbf9ee_1x400.png
│ │ │ │ │ ├── ui-bg_glass_65_ffffff_1x400.png
│ │ │ │ │ ├── ui-bg_glass_75_dadada_1x400.png
│ │ │ │ │ ├── ui-bg_glass_75_e6e6e6_1x400.png
│ │ │ │ │ ├── ui-bg_glass_95_fef1ec_1x400.png
│ │ │ │ │ ├── ui-bg_highlight-soft_75_cccccc_1x100.png
│ │ │ │ │ ├── ui-icons_222222_256x240.png
│ │ │ │ │ ├── ui-icons_2e83ff_256x240.png
│ │ │ │ │ ├── ui-icons_454545_256x240.png
│ │ │ │ │ ├── ui-icons_888888_256x240.png
│ │ │ │ │ └── ui-icons_cd0a0a_256x240.png
│ │ │ │ │ └── jquery-ui-1.8.13.custom.css
│ │ │ ├── images
│ │ │ │ ├── elrte-toolbar.png
│ │ │ │ ├── google-maps.png
│ │ │ │ ├── iframe.png
│ │ │ │ ├── loading.gif
│ │ │ │ ├── media-director.png
│ │ │ │ ├── media-flash.png
│ │ │ │ ├── media-quicktime.png
│ │ │ │ ├── media-realaudio.png
│ │ │ │ ├── media-rutube.png
│ │ │ │ ├── media-vimeo.png
│ │ │ │ ├── media-winmedia.png
│ │ │ │ ├── media-youtube.png
│ │ │ │ ├── outline-div.png
│ │ │ │ ├── outline-p.png
│ │ │ │ ├── pagebreak.gif
│ │ │ │ ├── pixel.gif
│ │ │ │ ├── smileys
│ │ │ │ │ ├── evilgrin.png
│ │ │ │ │ ├── grin.png
│ │ │ │ │ ├── happy.png
│ │ │ │ │ ├── smile.png
│ │ │ │ │ ├── surprised.png
│ │ │ │ │ ├── tongue.png
│ │ │ │ │ ├── unhappy.png
│ │ │ │ │ ├── waii.png
│ │ │ │ │ └── wink.png
│ │ │ │ └── yandex-maps.png
│ │ │ └── js
│ │ │ │ ├── elRTE.options.js
│ │ │ │ ├── elrte.full.js
│ │ │ │ ├── elrte.min.js
│ │ │ │ └── i18n
│ │ │ │ ├── elrte.YOUR_LANG.js
│ │ │ │ ├── elrte.ar.js
│ │ │ │ ├── elrte.ca.js
│ │ │ │ ├── elrte.cs.js
│ │ │ │ ├── elrte.da.js
│ │ │ │ ├── elrte.de.js
│ │ │ │ ├── elrte.en.js
│ │ │ │ ├── elrte.es.js
│ │ │ │ ├── elrte.fa.js
│ │ │ │ ├── elrte.fr.js
│ │ │ │ ├── elrte.hr.js
│ │ │ │ ├── elrte.hu.js
│ │ │ │ ├── elrte.it.js
│ │ │ │ ├── elrte.jp.js
│ │ │ │ ├── elrte.ko.js
│ │ │ │ ├── elrte.lv.js
│ │ │ │ ├── elrte.nl.js
│ │ │ │ ├── elrte.pl.js
│ │ │ │ ├── elrte.pt_BR.js
│ │ │ │ ├── elrte.ru.js
│ │ │ │ ├── elrte.sk.js
│ │ │ │ ├── elrte.th.js
│ │ │ │ ├── elrte.tr.js
│ │ │ │ ├── elrte.uk.js
│ │ │ │ ├── elrte.vi.js
│ │ │ │ ├── elrte.zh_CN.js
│ │ │ │ └── elrte.zh_TW.js
│ │ │ ├── entry_editor.js
│ │ │ ├── jquery
│ │ │ ├── jquery-timepicker-addons
│ │ │ │ ├── i18n
│ │ │ │ │ ├── jquery-ui-timepicker-af.js
│ │ │ │ │ ├── jquery-ui-timepicker-am.js
│ │ │ │ │ ├── jquery-ui-timepicker-bg.js
│ │ │ │ │ ├── jquery-ui-timepicker-ca.js
│ │ │ │ │ ├── jquery-ui-timepicker-cs.js
│ │ │ │ │ ├── jquery-ui-timepicker-da.js
│ │ │ │ │ ├── jquery-ui-timepicker-de.js
│ │ │ │ │ ├── jquery-ui-timepicker-el.js
│ │ │ │ │ ├── jquery-ui-timepicker-es.js
│ │ │ │ │ ├── jquery-ui-timepicker-et.js
│ │ │ │ │ ├── jquery-ui-timepicker-eu.js
│ │ │ │ │ ├── jquery-ui-timepicker-fi.js
│ │ │ │ │ ├── jquery-ui-timepicker-fr.js
│ │ │ │ │ ├── jquery-ui-timepicker-gl.js
│ │ │ │ │ ├── jquery-ui-timepicker-he.js
│ │ │ │ │ ├── jquery-ui-timepicker-hr.js
│ │ │ │ │ ├── jquery-ui-timepicker-hu.js
│ │ │ │ │ ├── jquery-ui-timepicker-id.js
│ │ │ │ │ ├── jquery-ui-timepicker-it.js
│ │ │ │ │ ├── jquery-ui-timepicker-ja.js
│ │ │ │ │ ├── jquery-ui-timepicker-ko.js
│ │ │ │ │ ├── jquery-ui-timepicker-lt.js
│ │ │ │ │ ├── jquery-ui-timepicker-nl.js
│ │ │ │ │ ├── jquery-ui-timepicker-no.js
│ │ │ │ │ ├── jquery-ui-timepicker-pl.js
│ │ │ │ │ ├── jquery-ui-timepicker-pt-BR.js
│ │ │ │ │ ├── jquery-ui-timepicker-pt.js
│ │ │ │ │ ├── jquery-ui-timepicker-ro.js
│ │ │ │ │ ├── jquery-ui-timepicker-ru.js
│ │ │ │ │ ├── jquery-ui-timepicker-sk.js
│ │ │ │ │ ├── jquery-ui-timepicker-sr-RS.js
│ │ │ │ │ ├── jquery-ui-timepicker-sr-YU.js
│ │ │ │ │ ├── jquery-ui-timepicker-sv.js
│ │ │ │ │ ├── jquery-ui-timepicker-th.js
│ │ │ │ │ ├── jquery-ui-timepicker-tr.js
│ │ │ │ │ ├── jquery-ui-timepicker-uk.js
│ │ │ │ │ ├── jquery-ui-timepicker-vi.js
│ │ │ │ │ ├── jquery-ui-timepicker-zh-CN.js
│ │ │ │ │ └── jquery-ui-timepicker-zh-TW.js
│ │ │ │ ├── jquery-ui-timepicker-addon.css
│ │ │ │ └── jquery-ui-timepicker-addon.js
│ │ │ ├── jquery-toggles
│ │ │ │ └── toggles.min.js
│ │ │ └── jquery.fc2tab.js
│ │ │ ├── search_form.js
│ │ │ ├── sp
│ │ │ ├── jquery.accordion.js
│ │ │ ├── jquery.fc2tab.js
│ │ │ └── jquery.slideMenu.js
│ │ │ └── syntax_check.js
│ ├── css
│ │ ├── normalize.css
│ │ ├── sp
│ │ │ └── user_layout_default.css
│ │ └── user_layout_default.css
│ ├── img
│ │ └── private_lock_icon.png
│ └── js
│ │ ├── common.js
│ │ ├── common_design.js
│ │ ├── jquery-ui
│ │ ├── images
│ │ │ ├── ui-bg_diagonals-thick_18_b81900_40x40.png
│ │ │ ├── ui-bg_diagonals-thick_20_666666_40x40.png
│ │ │ ├── ui-bg_flat_10_000000_40x100.png
│ │ │ ├── ui-bg_glass_100_f6f6f6_1x400.png
│ │ │ ├── ui-bg_glass_100_fdf5ce_1x400.png
│ │ │ ├── ui-bg_glass_65_ffffff_1x400.png
│ │ │ ├── ui-bg_gloss-wave_35_f6a828_500x100.png
│ │ │ ├── ui-bg_highlight-soft_100_eeeeee_1x100.png
│ │ │ ├── ui-bg_highlight-soft_75_ffe45c_1x100.png
│ │ │ ├── ui-icons_222222_256x240.png
│ │ │ ├── ui-icons_228ef1_256x240.png
│ │ │ ├── ui-icons_444444_256x240.png
│ │ │ ├── ui-icons_555555_256x240.png
│ │ │ ├── ui-icons_777620_256x240.png
│ │ │ ├── ui-icons_777777_256x240.png
│ │ │ ├── ui-icons_cc0000_256x240.png
│ │ │ ├── ui-icons_ef8c08_256x240.png
│ │ │ ├── ui-icons_ffd27a_256x240.png
│ │ │ └── ui-icons_ffffff_256x240.png
│ │ ├── jquery-ui.min.css
│ │ ├── jquery-ui.min.js
│ │ └── jquery.ui.touch-punch.min.js
│ │ ├── jquery.js
│ │ └── js.cookie.js
├── index.php
├── uploads
│ └── .gitkeep
└── user_uploads
│ └── README.txt
├── shell
└── i18n_convert_mo_to_po.sh
└── tests
├── App
├── Controller
│ ├── Admin
│ │ ├── BlogSettings
│ │ │ ├── CommentEditTest.php
│ │ │ ├── EntryEditTest.php
│ │ │ └── EtcEditTest.php
│ │ ├── BlogTemplates
│ │ │ ├── ApplyTest.php
│ │ │ ├── CreateTest.php
│ │ │ ├── EditTest.php
│ │ │ ├── Fc2IndexTest.php
│ │ │ ├── IndexTest.php
│ │ │ └── PreviewTest.php
│ │ ├── Blogs
│ │ │ ├── ChoiceTest.php
│ │ │ ├── CreateTest.php
│ │ │ ├── DeleteTest.php
│ │ │ ├── EditTest.php
│ │ │ └── IndexTest.php
│ │ ├── Categories
│ │ │ └── CreateTest.php
│ │ ├── Comments
│ │ │ └── IndexTest.php
│ │ ├── Common
│ │ │ ├── InstallTest.php
│ │ │ ├── LangTest.php
│ │ │ └── NoticeTest.php
│ │ ├── Entries
│ │ │ ├── CreateTest.php
│ │ │ ├── DeleteTest.php
│ │ │ ├── EditTest.php
│ │ │ └── IndexTest.php
│ │ ├── Files
│ │ │ ├── AjaxDeleteTest.php
│ │ │ ├── DeleteTest.php
│ │ │ ├── EditTest.php
│ │ │ └── UploadTest.php
│ │ ├── Tags
│ │ │ ├── DeleteTest.php
│ │ │ ├── EditTest.php
│ │ │ └── IndexTest.php
│ │ └── Users
│ │ │ ├── EditTest.php
│ │ │ ├── LogInTest.php
│ │ │ └── WithdrawalTest.php
│ └── User
│ │ ├── BlogsController
│ │ └── FeedTest.php
│ │ └── EntriesController
│ │ ├── CommentTest.php
│ │ └── IndexTest.php
├── Core
│ ├── App
│ │ └── GetRandomStringTest.php
│ ├── Controller
│ │ ├── HttpsHttpRedirectTest.php
│ │ └── LangTest.php
│ ├── Cookie
│ │ └── SetTest.php
│ ├── Html
│ │ └── UrlTest.php
│ └── Router
│ │ └── RouterTest.php
├── DefaultBlogIdMode
│ └── UrlTest.php
├── Fc2Template
│ ├── Fc2TemplateIfTest.php
│ ├── Fc2TemplateLoopTest.php
│ └── Fc2TemplateTest.php
├── Lib
│ ├── CaptchaImage
│ │ ├── .gitignore
│ │ └── DrawNumberTest.php
│ └── HtmlText.php
├── Model
│ ├── BlogsModel
│ │ ├── GetFullHostUrlByBlogIdTest.php
│ │ ├── GetSchemaByBlogIdTest.php
│ │ ├── GetSchemaBySslEnableValueTest.php
│ │ ├── IsCorrectHttpSchemaByBlogArrayTest.php
│ │ └── IsValidBlogIdTest.php
│ ├── CommentsModel
│ │ └── PasswordCheckTest.php
│ ├── PasswordResetTokenTest.php
│ └── UserTest.php
└── Service
│ ├── AccessBlockTest.php
│ ├── MailServiceTest.php
│ └── UserServiceTest.php
├── DBHelper.php
├── Helper
├── ClientTrait.php
└── SampleDataGenerator
│ ├── FakerTrait.php
│ ├── GenerateSampleBlog.php
│ ├── GenerateSampleCategory.php
│ ├── GenerateSampleComment.php
│ ├── GenerateSampleEntry.php
│ ├── GenerateSampleTag.php
│ ├── GenerateSampleTemplate.php
│ ├── GenerateSampleUploadFile.php
│ └── RandomUtilTrait.php
├── LoaderHelper.php
├── TestTest.php
├── bootstrap.php
├── cli_drop_all_table.php
├── cli_generate_sample_blog.php
├── cli_generate_sample_category.php
├── cli_generate_sample_comment.php
├── cli_generate_sample_entries.php
├── cli_generate_sample_tag.php
├── cli_generate_sample_template.php
├── cli_generate_sample_upload_image.php
├── cli_load_fixture.php
├── cli_update_template.php
├── test_drop_all_table.sql
├── test_fixture.sql
└── test_images
├── .gitignore
└── download_samples.sh
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Test All
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | pull_request:
8 | branches:
9 | - master
10 |
11 | jobs:
12 | test:
13 | runs-on: ubuntu-latest
14 | steps:
15 | - uses: actions/checkout@v2
16 |
17 | - name: build docker image
18 | run: make docker-compose-build
19 |
20 | - name: docker-compose up
21 | run: docker-compose up -d
22 |
23 | - name: wait and debug output
24 | run: |
25 | sleep 10
26 | docker ps -a
27 | curl -v http://127.0.0.1:8080
28 |
29 | - name: Execute tests
30 | run: make test
31 |
32 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /app/temp/blog_template/*
2 | /app/temp/debug_html/*
3 | /app/temp/log/*
4 | /app/temp/installed.lock
5 | /app/temp/GeoLite2-Country.mmdb
6 | /app/temp/github_release_cache.json
7 | /app/version
8 | /app/vendor/
9 | /public/uploads/[0-9a-zA-Z]
10 | /public/config.php
11 | /dump_data.sql
12 | /dump_all.sql
13 | /dump_schema.sql
14 | composer.phar
15 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 FC2, Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | blog
2 | ====
3 |
4 | Open Source Blog
5 |
6 | #### Operating Environment
7 |
8 | * PHP 7.3 or higher
9 | * MySQL 5.5 or higher
10 |
11 | #### Installation
12 |
13 | 1. Download the .git or .zip file, and extract it to the server.
14 | app
15 | public [public directory]
16 |
17 | 2. Change the name of the settings file, and store the DB or Server information.
18 | app/config.sample.php -> app/config.php
19 |
20 | *If the `app` directory does not exist on the same level as the `public` directory, you will need to amend the path from
21 | the following area in the `index.php`, `admin/index.php` files.
22 |
23 | ```
24 | $app_dir_path = __DIR__ . "/../app";
25 | to
26 | $app_dir_path = "/path/to/your/www/app";
27 | ```
28 |
29 | 3. Access the Installation Screen
30 | [DOMAIN]/admin/common/install
31 |
32 | 4. Follow the instructions and complete installation.
33 |
34 | 5. Once installation is complete, admin/install.php will no longer be necessary. Please delete it.
35 |
36 | #### test to use or development, with Docker.
37 |
38 | 1. Mac: run `docker-compose up`. Linux: run `make docker-compose-build` and then `docker-compose up`.
39 | 2. open `http://localhost:8080/admin/common/install`
40 |
41 | * If you use Docker, you may don't need to create or edit `app/config.php`.
42 | * If you want to test https. open `https://localhost:8480/admin/common/install` .
43 |
44 | #### unit test
45 |
46 | ```
47 | $ make test
48 | ```
49 |
50 | * If you want to know "what's going on?", Please see the `Makefile`.
51 | * Require Docker&docker-compose, PHP, node.js runtimes.
52 | * If you got DB connection error on first run, please wait mysql initialize and retry.
53 |
--------------------------------------------------------------------------------
/app/.htaccess:
--------------------------------------------------------------------------------
1 | order deny,allow
2 | deny from all
3 |
4 |
--------------------------------------------------------------------------------
/app/config.sample.php:
--------------------------------------------------------------------------------
1 | getBlogId($request);
16 | // if (empty($blog_id)) {
17 | // // blog_idが指定されていない場合は処理しない
18 | // // cron実行時であればblog_id無し(全体)で処理を行う
19 | // return ;
20 | // }
21 | //
22 | // $entriesModel = Model::load('Entries');
23 | //
24 | // // 予約投稿処理
25 | // $entriesModel->updateReservation($blog_id);
26 | //
27 | // // 期間限定処理
28 | // $entriesModel->updateLimited($blog_id);
29 | // }
30 | //
31 | //}
32 |
33 |
--------------------------------------------------------------------------------
/app/src/Exception/PseudoExit.php:
--------------------------------------------------------------------------------
1 | render($twig_template, $template_params);
27 | [$subject, $body] = explode("\n==\n", $mail_sub_and_body, 2);
28 | $this->subject = $subject;
29 | $this->body = $body;
30 | }
31 |
32 | public function setTo(string $email_addr, string $name = ""): void
33 | {
34 | $this->to = $email_addr;
35 | $this->toName = $name;
36 | }
37 |
38 | public function setFrom(string $email_addr, string $name = ""): void
39 | {
40 | $this->from = $email_addr;
41 | $this->fromName = $name;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/app/src/Model/EmailLoginToken.php:
--------------------------------------------------------------------------------
1 | user_id = $user->id;
23 | $self->token = App::genRandomString();
24 | $self->expire_at = date("Y-m-d H:i:s", time() + 60 * 60 * 24);
25 | $self->updated_at = date("Y-m-d H:i:s");
26 | $self->created_at = date("Y-m-d H:i:s");
27 | return $self;
28 | }
29 |
30 | public static function factoryFromArray(array $list): self
31 | {
32 | $self = new static();
33 | $self->id = $list['id'];
34 | $self->user_id = $list['user_id'];
35 | $self->token = $list['token'];
36 | $self->expire_at = $list['expire_at'];
37 | $self->updated_at = $list['updated_at'];
38 | $self->created_at = $list['created_at'];
39 | return $self;
40 | }
41 |
42 | public function isExpired(): bool
43 | {
44 | return strtotime($this->expire_at) < time();
45 | }
46 |
47 | public function getLoginUrl(Request $request): string
48 | {
49 | return Html::adminUrl(
50 | $request,
51 | 'Session',
52 | 'mailLogin',
53 | ['token' => $this->token],
54 | true
55 | );
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/app/src/Model/EmailLoginTokenModel.php:
--------------------------------------------------------------------------------
1 | validates = array(
24 | 'login_id' => array(
25 | 'required' => true,
26 | 'maxlength' => array('max' => 512),
27 | ),
28 | );
29 |
30 | return parent::validate($data, $valid_data, $white_list);
31 | }
32 |
33 | /**
34 | * @param array $values
35 | * @param array $options
36 | * @return int|null last insert id or null
37 | */
38 | public function insert(array $values, array $options = []): ?int
39 | {
40 | unset($values['id']); // insertのため、pkを削除
41 | $values['updated_at'] = $values['created_at'] = date('Y-m-d H:i:s');
42 | $last_insert_id = parent::insert($values, $options);
43 | return $last_insert_id === false ? null : (int)$last_insert_id;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/app/src/Model/PDOConnection.php:
--------------------------------------------------------------------------------
1 | pdo = static::createConnection();
18 | }
19 | return self::$instance;
20 | }
21 |
22 | /** @var PDO */
23 | public $pdo;
24 |
25 | public static function createConnection(): PDO
26 | {
27 | $host = DB_HOST;
28 | $port = DB_PORT;
29 | $user = DB_USER;
30 | $password = DB_PASSWORD;
31 | $database = DB_DATABASE;
32 | $charset = DB_CHARSET;
33 |
34 | return new PDO(
35 | "mysql:host={$host};port={$port};dbname={$database};charset={$charset};",
36 | $user,
37 | $password,
38 | [
39 | PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
40 | PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
41 | PDO::ATTR_EMULATE_PREPARES => false,
42 | ]
43 | );
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/app/src/Model/PasswordResetToken.php:
--------------------------------------------------------------------------------
1 | user_id = $user->id;
23 | $self->token = App::genRandomString();
24 | $self->expire_at = date("Y-m-d H:i:s", time() + 60 * 60 * 24);
25 | $self->updated_at = date("Y-m-d H:i:s");
26 | $self->created_at = date("Y-m-d H:i:s");
27 | return $self;
28 | }
29 |
30 | public static function factoryFromArray(array $list): self
31 | {
32 | $self = new static();
33 | $self->id = $list['id'];
34 | $self->user_id = $list['user_id'];
35 | $self->token = $list['token'];
36 | $self->expire_at = $list['expire_at'];
37 | $self->updated_at = $list['updated_at'];
38 | $self->created_at = $list['created_at'];
39 | return $self;
40 | }
41 |
42 | public function isExpired(): bool
43 | {
44 | return strtotime($this->expire_at) < time();
45 | }
46 |
47 | public function getResetUrl(Request $request): string
48 | {
49 | return Html::adminUrl(
50 | $request,
51 | 'PasswordReset',
52 | 'resetForm',
53 | ['token' => $this->token],
54 | true
55 | );
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/app/src/Model/PasswordResetTokenModel.php:
--------------------------------------------------------------------------------
1 | validates = array(
24 | 'login_id' => array(
25 | 'required' => true,
26 | 'maxlength' => array('max' => 512),
27 | ),
28 | );
29 |
30 | return parent::validate($data, $valid_data, $white_list);
31 | }
32 |
33 | /**
34 | * @param array $values
35 | * @param array $options
36 | * @return int|null last insert id or null
37 | */
38 | public function insert(array $values, array $options = []): ?int
39 | {
40 | unset($values['id']); // insertのため、pkを削除
41 | $values['updated_at'] = $values['created_at'] = date('Y-m-d H:i:s');
42 | $last_insert_id = parent::insert($values, $options);
43 | return $last_insert_id === false ? null : (int)$last_insert_id;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/app/src/Model/User.php:
--------------------------------------------------------------------------------
1 | password = UsersModel::passwordHash($password);
25 | }
26 |
27 | public function verifyPassword(string $input_password): bool
28 | {
29 | return password_verify($input_password, $this->password);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/Repo/MailerInterface.php:
--------------------------------------------------------------------------------
1 | setSubject($email->subject)
28 | ->setFrom([$email->from => $email->fromName])
29 | ->setTo([$email->to => $email->toName])
30 | ->setBody($email->body);
31 | } /** @noinspection PhpRedundantCatchClauseInspection */ catch (Swift_RfcComplianceException $e) {
32 | error_log("mail address is invalid. please check login_id or ADMIN_MAIL_ADDRESS configuration " . $e->getMessage() . " " . print_r($email, true));
33 | return false;
34 | }
35 |
36 | try {
37 | $resultNum = $mailer->send($message);
38 | return $resultNum > 0;
39 | } catch (Exception $e) {
40 | // ignore mail sending error.
41 | error_log("mail send failed. please check sendmail configuration. " . $e->getMessage() . " " . print_r($email, true));
42 | return false;
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/app/src/Repo/StdErrOutputMailer.php:
--------------------------------------------------------------------------------
1 | findById($blog_id);
17 | if ($res === false) return null;
18 | return Blog::factory($res);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/Service/MailService.php:
--------------------------------------------------------------------------------
1 | send($email);
18 | }
19 |
20 | public static function getMailer(): MailerInterface
21 | {
22 | return new static::$mailerClassName();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/Service/TwigService.php:
--------------------------------------------------------------------------------
1 | getFunctions(),
32 | (new HtmlHelper())->getFunctions(),
33 | ) as $function) {
34 | $twig->addFunction($function);
35 | }
36 |
37 | static::$twigInstance = $twig;
38 | }
39 |
40 | return static::$twigInstance;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/app/src/Service/UserService.php:
--------------------------------------------------------------------------------
1 | findByLoginId($login_id));
15 | }
16 |
17 | public static function getByLoginIdAndPassword(string $login_id, string $password): ?User
18 | {
19 | $repo = new UsersModel();
20 | $row = $repo->findByLoginId($login_id);
21 | if ($row === false) return null;
22 | $user = User::factory($row);
23 | return !is_null($user) && $user->verifyPassword($password) ? $user : null;
24 | }
25 |
26 | public static function updatePassword(User $user, string $password): bool
27 | {
28 | $user->setPassword($password);
29 | return UserService::update($user);
30 | }
31 |
32 | public static function update(User $user): bool
33 | {
34 | $repo = new UsersModel();
35 | return $repo->updateById($user->asArray(), $user->id) === 1;
36 | }
37 |
38 | public static function getById(int $user_id): ?User
39 | {
40 | $repo = new UsersModel();
41 | $res = $repo->findById($user_id);
42 | if ($res === false) return null;
43 | return User::factory($res);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/app/src/Util/PhpCodeLinter.php:
--------------------------------------------------------------------------------
1 | create(ParserFactory::PREFER_PHP7);
20 | try {
21 | $parser->parse($string);
22 | } catch (Error $error) {
23 | return false;
24 | }
25 | return true;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/Util/StringCaseConverter.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/blog_plugins/register.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default.twig' %}
2 | {% block title %}{{ _('Registration of plug-in') }}{% endblock %}
3 |
4 | {% block content %}
5 | {{ _('Registration of plug-in') }}
6 |
9 |
10 |
37 | {% endblock %}
38 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/blog_settings/etc_edit.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default.twig' %}
2 | {% block title %}{{ _('Other Settings') }}{% endblock %}
3 |
4 | {% block content %}
5 | {{ _('Other Settings') }}
6 |
7 | {% include('admin/blog_settings/tab.twig') %}
8 |
9 |
10 |
11 |
27 |
28 |
29 |
30 | {% endblock %}
31 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/blog_settings/etc_edit_sp.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default_sp.twig' %}
2 | {% block title %}{{ _('Other Settings') }}{% endblock %}
3 |
4 | {% block content %}
5 | {{ _('Other Settings') }}
6 |
7 | {% include('admin/blog_settings/tab_sp.twig') %}
8 |
9 | {{ _('Setting') }}
10 |
25 | {% endblock %}
26 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/blog_settings/tab.twig:
--------------------------------------------------------------------------------
1 |
18 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/blog_settings/tab_sp.twig:
--------------------------------------------------------------------------------
1 |
18 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/blog_templates/fc2_index_sp.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default_sp.twig' %}
2 | {% block title %}{{ _('FC2 Template list') }}{% endblock %}
3 |
4 | {% block content %}
5 |
6 | {{ _('FC2 Template list') }}[{{ _(attribute(constant('Fc2blog\\App::DEVICE_FC2_KEY'), req_device_type)) }}]
7 |
8 | {% if templates %}
9 |
19 | {% endif %}
20 | {% if not templates %}
21 | {{ _('FC2 template can not be found') }}
22 | {% endif %}
23 |
24 | {% include('admin/common/paging_sp.twig') %}
25 |
26 | {% endblock %}
--------------------------------------------------------------------------------
/app/twig_templates/admin/blog_templates/fc2_view.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default.twig' %}
2 | {% block title %}{{ _('FC2 Template detail') }}{% endblock %}
3 |
4 | {% block content %}
5 |
6 | This page is not support your device.
7 |
8 | {% endblock %}
--------------------------------------------------------------------------------
/app/twig_templates/admin/blog_templates/form_js.twig:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/blogs/create.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default.twig' %}
2 | {% block title %}{{ _('New registration of the blog') }}{% endblock %}
3 |
4 | {% block content %}
5 | {{ _('New registration of the blog') }}
6 |
7 |
43 | {% endblock %}
44 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/blogs/create_sp.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default_sp.twig' %}
2 | {% block title %}{{ _('New registration of the blog') }}{% endblock %}
3 |
4 | {% block content %}
5 | {{ _('New registration of the blog') }}
6 |
7 |
32 | {% endblock %}
33 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/blogs/delete.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default.twig' %}
2 | {% block title %}{{ _('Blog Delete') }}{% endblock %}
3 |
4 | {% block content %}
5 |
6 |
7 | {% include('admin/blog_settings/tab.twig') %}
8 |
9 |
28 |
29 |
42 | {% endblock %}
43 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/blogs/index.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default.twig' %}
2 | {% block title %}{{ _('List of blogs') }}{% endblock %}
3 |
4 | {% block content %}
5 |
6 |
7 |
8 |
9 |
27 |
28 | {% include('admin/common/paging.twig') %}
29 |
30 | {% endblock %}
31 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/blogs/index_sp.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default_sp.twig' %}
2 | {% block title %}{{ _('List of blogs') }}{% endblock %}
3 |
4 | {% block content %}
5 |
6 |
7 |
10 |
11 | {{ _('Blog ID') }}
12 |
13 |
14 | {% for blog in blogs %}
15 | -
16 | {{ blog.id }}
17 |
18 | {% endfor %}
19 |
20 |
21 | {% include('admin/common/paging_sp.twig') %}
22 |
23 | {% endblock %}
24 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/categories/edit.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default.twig' %}
2 | {% block title %}{{ _('I edit a category') }}{% endblock %}
3 |
4 | {% block content %}
5 | {{ _('I edit a category') }}
6 |
7 |
45 | {% endblock %}
46 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/comments/reply.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default.twig' %}
2 | {% block title %}{{ _('Details of comment') }}{% endblock %}
3 |
4 | {% block content %}
5 | The url is only for smartphone.
6 |
7 | please move back to comments list page.
8 |
11 | {% endblock %}
12 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/common/error404.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default.twig' %}
2 | {% block title %}{{ _('404 Not Found.') }}{% endblock %}
3 |
4 | {% block content %}
5 | {{ _('404 Not Found.') }} {{ _("The page you are looking for does not exist.") }}
6 | {% endblock %}
7 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/common/error404_sp.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default_sp.twig' %}
2 | {% block title %}{{ _('404 Not Found.') }}{% endblock %}
3 |
4 | {% block content %}
5 | {{ _('404 Not Found.') }}
6 | {{ _("The page you are looking for does not exist.") }}
7 | {% endblock %}
8 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/common/installed.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default_nomenu.twig' %}
2 | {% block title %}{{ _('Installation complete') }}{% endblock %}
3 |
4 | {% block content %}
5 | {{ _('Installation complete') }}
6 |
7 | {{ _('The installation was completed') }}
8 | {{ _('Please log from the following') }}
9 | {{ _('Login') }}
10 | {{ _('If you want to re-enable this installer, please delete `installed.lock` file in temp dir.') }}
11 | {% endblock %}
12 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/common/json.twig:
--------------------------------------------------------------------------------
1 | {{ json|json_encode()|raw }}
--------------------------------------------------------------------------------
/app/twig_templates/admin/common/notice.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default.twig' %}
2 | {% block title %}{{ _('Login to Administration page') }}{% endblock %}
3 |
4 | {% block content %}
5 |
6 | {% if unread_count %}
7 |
8 |
9 | {{ _s('There %d reviews unread comments', unread_count) }}
10 |
11 |
12 | {% endif %}
13 |
14 | {% if unapproved_count %}
15 |
16 |
17 | {{ _s('There %d reviews unapproved comment', unapproved_count) }}
18 |
19 |
20 | {% endif %}
21 |
22 | {% if not unread_count and not unapproved_count %}
23 | {{ _('There is no notice') }}
24 | {% endif %}
25 | {% endblock %}
26 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/common/paging.twig:
--------------------------------------------------------------------------------
1 | {# @var req \Fc2blog\Web\Request #}
2 |
3 |
4 | {% if paging.is_prev %}
5 | - <<
6 | {% endif %}
7 |
8 | {% if paging.is_prev %}
9 | - <
10 | {% endif %}
11 |
12 | {% if 0 < paging.start %}
13 | - <
14 | {% endif %}
15 |
16 | {% if 1 < paging.start %}
17 | - ...
18 | {% endif %}
19 |
20 | {% if paging.end == 0 %}
21 | - 1
22 | {% else %}
23 | {% for i in range(paging.start, paging.end-1) %}
24 | {% if paging.page == i %}
25 | - {{ i+1 }}
26 | {% endif %}
27 | {% if paging.page != i %}
28 | - {{ i+1 }}
29 | {% endif %}
30 | {% endfor %}
31 | {% endif %}
32 |
33 | {% if paging.end < (paging.max_page-1) %}
34 | - ...
35 | {% endif %}
36 |
37 | {% if paging.end < paging.max_page %}
38 | - {{ paging.max_page }}
39 | {% endif %}
40 |
41 | {% if paging.is_next %}
42 | - >
43 | {% endif %}
44 |
45 | {% if paging.is_next %}
46 | - >>
47 | {% endif %}
48 |
49 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/common/paging_sp.twig:
--------------------------------------------------------------------------------
1 | {# @var req \Fc2blog\Web\Request #}
2 |
3 |
4 |
5 |
6 |
{{ paging.page+1 }} / {{ paging.max_page }}
7 |
8 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/email_login/expired.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default.twig' %}
2 | {% block title %}{{ _('Login request expired.') }}{% endblock %}
3 |
4 | {% block content %}
5 | {{ _('Login request expired.') }}
6 |
7 |
8 |
{{ _("Login request was expired. Please try again login form.") }}
9 |
10 | {% endblock %}
11 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/email_login/mail_sending_error.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default.twig' %}
2 | {% block title %}{{ _('Mail sending error.') }}{% endblock %}
3 |
4 | {% block content %}
5 | {{ _('Mail sending error.') }}
6 |
7 |
8 |
{{ _("Could not sent mail. Please check error log.") }}
9 |
{{ _("Some thoughts reason: 1, wrong sendmail configuration. 2, from/to mail address was invalid.") }}
10 |
11 | {% endblock %}
12 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/email_login/requested.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default.twig' %}
2 | {% block title %}{{ _('Sent login mail.') }}{% endblock %}
3 |
4 | {% block content %}
5 | {{ _('Sent login mail.') }}
6 |
7 |
8 |
{{ _("Sent one time login url to your mail address. Please check your mailbox.") }}
9 |
{{ _("If you do not receive a password reset mail, please check your spam folder.") }}
10 |
11 | {% endblock %}
12 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/entries/create.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default.twig' %}
2 | {% block title %}{{ _('Write a new entry') }}{% endblock %}
3 |
4 | {% block content %}
5 | {{ _('Write a new entry') }}
6 |
10 | {% endblock %}
11 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/entries/create_sp.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default_sp.twig' %}
2 | {% block title %}{{ _('Write a new entry') }}{% endblock %}
3 |
4 | {% block content %}
5 | {{ _('Write a new entry') }}
6 |
10 | {% endblock %}
11 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/entries/edit.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default.twig' %}
2 | {% block title %}{{ _('Edit this entry.') }}{% endblock %}
3 |
4 | {% block content %}
5 | {{ _('Edit this entry.') }}
6 |
11 | {% endblock %}
12 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/entries/edit_sp.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default_sp.twig' %}
2 | {% block title %}{{ _('Edit this entry.') }}{% endblock %}
3 | {# @var req \Fc2blog\Web\Request #}
4 |
5 | {% block content %}
6 | {{ _('Edit this entry.') }}
7 |
12 |
13 | {{ _('Delete entry') }}
14 |
23 |
24 |
30 |
40 |
41 | {% endblock %}
42 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/flagments/flash_message.twig:
--------------------------------------------------------------------------------
1 | {% if flash_messages.error %}
2 |
3 |
4 | {% for flash_error in flash_messages.error %}
5 |
{{ flash_error }}
6 | {% endfor %}
7 |
8 | {% endif %}
9 |
10 | {% if flash_messages.warn %}
11 |
12 |
13 | {% for flash_warn in flash_messages.warn %}
14 |
{{ flash_warn }}
15 | {% endfor %}
16 |
17 | {% endif %}
18 |
19 | {% if flash_messages.info %}
20 |
21 |
22 | {% for flash_info in flash_messages.info %}
23 |
{{ flash_info }}
24 | {% endfor %}
25 |
26 | {% endif %}
27 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/flagments/flash_message_sp.twig:
--------------------------------------------------------------------------------
1 | {% if flash_messages.error %}
2 |
3 |
4 | {% for flash_error in flash_messages.error %}
5 |
{{ flash_error }}
6 | {% endfor %}
7 |
8 | {% endif %}
9 |
10 | {% if flash_messages.warn %}
11 |
12 |
13 | {% for flash_warn in flash_messages.warn %}
14 |
{{ flash_warn }}
15 | {% endfor %}
16 |
17 | {% endif %}
18 |
19 | {% if flash_messages.info %}
20 |
21 |
22 | {% for flash_info in flash_messages.info %}
23 |
{{ flash_info }}
24 | {% endfor %}
25 |
26 | {% endif %}
27 |
28 |
38 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/layouts/default_nomenu.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{ block('title') }}
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
18 |
19 |
20 |
21 |
31 |
32 |
33 |
34 | {% include 'admin/flagments/flash_message.twig' %}
35 | {{ block('content') }}
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/password_reset/complete.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default.twig' %}
2 | {% block title %}{{ _('Password reset completed.') }}{% endblock %}
3 |
4 | {% block content %}
5 | {{ _('Password reset completed.') }}
6 |
7 |
8 |
{{ _("Password reset completed. Please login form login page.") }}
9 |
10 | {% endblock %}
11 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/password_reset/expired.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default.twig' %}
2 | {% block title %}{{ _('Password reset request expired.') }}{% endblock %}
3 |
4 | {% block content %}
5 | {{ _('Password reset request expired.') }}
6 |
7 |
8 |
{{ _("The password reset request is expired. Please try again from reset request form.") }}
9 |
10 | {% endblock %}
11 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/password_reset/mail_sending_error.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default.twig' %}
2 | {% block title %}{{ _('Mail sending error.') }}{% endblock %}
3 |
4 | {% block content %}
5 | {{ _('Mail sending error.') }}
6 |
7 |
8 |
{{ _("Could not sent mail. Please check error log.") }}
9 |
{{ _("Some thoughts reason: 1, wrong sendmail configuration. 2, from/to mail address was invalid.") }}
10 |
11 | {% endblock %}
12 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/password_reset/request_form.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default.twig' %}
2 | {% block title %}{{ _('Password reset') }}{% endblock %}
3 |
4 | {% block content %}
5 | {{ _('Password reset request form') }}
6 |
7 |
25 | {% endblock %}
26 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/password_reset/requested.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default.twig' %}
2 | {% block title %}{{ _('Sent password reset mail') }}{% endblock %}
3 |
4 | {% block content %}
5 | {{ _('Sent password reset mail') }}
6 |
7 |
8 |
{{ _("Password reset mail submitted. Please check your mailbox.") }}
9 |
{{ _("If you do not receive a password reset mail, please check your spam folder.") }}
10 |
11 | {% endblock %}
12 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/password_reset/reset_form.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default.twig' %}
2 | {% block title %}{{ _('Password reset') }}{% endblock %}
3 |
4 | {% block content %}
5 | {{ _('Password reset') }}
6 |
7 |
30 | {% endblock %}
31 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/session/login.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default.twig' %}
2 | {% block title %}{{ _('Login to Administration page') }}{% endblock %}
3 |
4 | {% block content %}
5 |
6 |
41 | {% endblock %}
--------------------------------------------------------------------------------
/app/twig_templates/admin/session/login_sp.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default_sp.twig' %}
2 | {% block title %}{{ _('Login to Administration page') }}{% endblock %}
3 |
4 | {% block content %}
5 |
6 |
26 | {% endblock %}
--------------------------------------------------------------------------------
/app/twig_templates/admin/tags/edit.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default.twig' %}
2 | {% block title %}{{ _('I want to edit tags') }}{% endblock %}
3 |
4 | {% block content %}
5 | {{ _('I want to edit tags') }}
6 |
7 |
30 | {% endblock %}
31 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/tags/index_sp.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default_sp.twig' %}
2 | {% block title %}{{ _('List of tags') }}{% endblock %}
3 |
4 | {% block content %}
5 |
6 |
21 |
22 |
34 |
35 | {% include('admin/common/paging_sp.twig') %}
36 |
37 | {% endblock %}
--------------------------------------------------------------------------------
/app/twig_templates/admin/users/edit.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default.twig' %}
2 | {% block title %}{{ _('User setting') }}{% endblock %}
3 |
4 | {% block content %}
5 |
6 |
7 | {% include('admin/users/tab.twig') %}
8 |
9 |
37 |
38 | {% endblock %}
--------------------------------------------------------------------------------
/app/twig_templates/admin/users/edit_sp.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default_sp.twig' %}
2 | {% block title %}{{ _('User setting') }}{% endblock %}
3 |
4 | {% block content %}
5 |
6 |
7 |
8 | {% include('admin/users/tab_sp.twig') %}
9 |
10 | {{ _('Setting') }}
11 |
31 |
32 | {% endblock %}
33 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/users/index.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default.twig' %}
2 | {% block title %}{{ _('User setting') }}{% endblock %}
3 |
4 | {% block content %}
5 |
6 |
7 | {% for user in users %}
8 | {{ user.login_id }}
9 |
10 |
11 | {{ _('Blog ID') }} |
12 | {{ _('Blog name') }} |
13 | {{ _('Nickname') }} |
14 | |
15 |
16 | {% for blog in user.blog_list %}
17 |
18 | {{ blog.id }} |
19 | {{ blog.name }} |
20 | {{ blog.nickname }} |
21 |
22 | {{ _('Checking the blog') }}
23 | |
24 |
25 | {% endfor %}
26 |
27 | {% endfor %}
28 |
29 | {% include('admin/common/paging.twig') %}
30 | {% endblock %}
31 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/users/tab.twig:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/users/tab_sp.twig:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/app/twig_templates/admin/users/withdrawal.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layouts/default.twig' %}
2 | {% block title %}{{ _('Withdrawal process') }}{% endblock %}
3 |
4 | {% block content %}
5 | {{ _('Withdrawal process') }}
6 |
7 | {% include('admin/users/tab.twig') %}
8 |
9 |
30 |
31 |
44 | {% endblock %}
45 |
--------------------------------------------------------------------------------
/app/twig_templates/fragment/checkbox.twig:
--------------------------------------------------------------------------------
1 | {% for key, option in option_list %}{% endfor %}
--------------------------------------------------------------------------------
/app/twig_templates/fragment/file.twig:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/twig_templates/fragment/hidden.twig:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/twig_templates/fragment/li.twig:
--------------------------------------------------------------------------------
1 |
2 | {% include "fragment/radio.twig" %}
3 | {% include "fragment/radio_label.twig" %}
4 |
--------------------------------------------------------------------------------
/app/twig_templates/fragment/password.twig:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/twig_templates/fragment/radio.twig:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/twig_templates/fragment/radio_label.twig:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/twig_templates/fragment/select.twig:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/twig_templates/fragment/text.twig:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/twig_templates/fragment/textarea.twig:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/twig_templates/fragment/ul.twig:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/twig_templates/fragment/undefined.twig:
--------------------------------------------------------------------------------
1 | {{ type }}は未実装です
--------------------------------------------------------------------------------
/app/twig_templates/mail/email_login.twig:
--------------------------------------------------------------------------------
1 | {{ _('[Fc2blog OSS] Your login url') }}
2 | ==
3 | {{ _('You requested site login.') }}
4 |
5 | {{ _('! If you have no idea about this email, please ignore it. !') }}
6 |
7 | {{ _('You can login by the following URL.') }}
8 |
9 | {{ url }}
10 |
--------------------------------------------------------------------------------
/app/twig_templates/mail/password_recovery_request.twig:
--------------------------------------------------------------------------------
1 | {{ _('[Fc2blog OSS] Password reset requested') }}
2 | ==
3 | {{ _('You requested password reset.') }}
4 |
5 | {{ _('! If you have no idea about this email, please ignore it. !') }}
6 |
7 | {{ _('You can change your login password at the following URL.') }}
8 |
9 | {{ url }}
10 |
--------------------------------------------------------------------------------
/app/twig_templates/user/common/error400.twig:
--------------------------------------------------------------------------------
1 | {% extends 'user/layouts/default.twig' %}
2 | {% block title %}{{ _('400 BadRequest.') }}{% endblock %}
3 |
4 | {% block content %}
5 | {{ _('400 BadRequest.') }}
6 | {% endblock %}
7 |
--------------------------------------------------------------------------------
/app/twig_templates/user/common/error400_sp.twig:
--------------------------------------------------------------------------------
1 | {% extends 'user/layouts/default_sp.twig' %}
2 | {% block title %}{{ _('403 Forbidden.') }}{% endblock %}
3 |
4 | {% block content %}
5 | {{ _('400 BadRequest.') }}
6 | {% endblock %}
7 |
--------------------------------------------------------------------------------
/app/twig_templates/user/common/error403.twig:
--------------------------------------------------------------------------------
1 | {% extends 'user/layouts/default.twig' %}
2 | {% block title %}{{ _('403 Forbidden.') }}{% endblock %}
3 |
4 | {% block content %}
5 | {{ _('403 Forbidden.') }}
6 | {% endblock %}
7 |
--------------------------------------------------------------------------------
/app/twig_templates/user/common/error403_sp.twig:
--------------------------------------------------------------------------------
1 | {% extends 'user/layouts/default_sp.twig' %}
2 | {% block title %}{{ _('403 Forbidden.') }}{% endblock %}
3 |
4 | {% block content %}
5 | {{ _('403 Forbidden.') }}
6 | {% endblock %}
7 |
--------------------------------------------------------------------------------
/app/twig_templates/user/common/error404.twig:
--------------------------------------------------------------------------------
1 | {% extends 'user/layouts/default.twig' %}
2 | {% block title %}{{ _('404 Not Found.') }}{% endblock %}
3 |
4 | {% block content %}
5 | {{ _('404 Not Found.') }} {{ _("The page you are looking for does not exist.") }}
6 | {% endblock %}
7 |
--------------------------------------------------------------------------------
/app/twig_templates/user/common/error404_sp.twig:
--------------------------------------------------------------------------------
1 | {% extends 'user/layouts/default_sp.twig' %}
2 | {% block title %}{{ _('404 Not Found.') }}{% endblock %}
3 |
4 | {% block content %}
5 | {{ _('404 Not Found.') }}
6 | {{ _("The page you are looking for does not exist.") }}
7 | {% endblock %}
8 |
--------------------------------------------------------------------------------
/app/twig_templates/user/common/error500.twig:
--------------------------------------------------------------------------------
1 | {% extends 'user/layouts/default.twig' %}
2 | {% block title %}{{ _('500 Internal Server Error.') }}{% endblock %}
3 |
4 | {% block content %}
5 | {{ _('500 Internal Server Error.') }}
6 | {% endblock %}
7 |
--------------------------------------------------------------------------------
/app/twig_templates/user/common/error500_sp.twig:
--------------------------------------------------------------------------------
1 | {% extends 'user/layouts/default_sp.twig' %}
2 | {% block title %}{{ _('500 Internal Server Error.') }}{% endblock %}
3 |
4 | {% block content %}
5 | {{ _('500 Internal Server Error.') }}
6 | {% endblock %}
7 |
--------------------------------------------------------------------------------
/app/twig_templates/user/entries/blog_password.twig:
--------------------------------------------------------------------------------
1 | {% extends 'user/layouts/default.twig' %}
2 | {% block title %}{{ _('Password authentication') }}{% endblock %}
3 |
4 | {% block content %}
5 |
6 |
7 |
8 |
9 | {{ _('Password authentication') }}
10 |
11 | {{ _('Enter the password manager has set is required to view') }}
12 |
13 |
14 | |
15 |
16 |
30 | |
31 |
32 |
33 | {% endblock %}
34 |
--------------------------------------------------------------------------------
/app/twig_templates/user/entries/blog_password_sp.twig:
--------------------------------------------------------------------------------
1 | {% extends 'user/layouts/default_sp.twig' %}
2 | {% block title %}{{ _('Password authentication') }}{% endblock %}
3 |
4 | {% block content %}
5 |
34 | {% endblock %}
35 |
--------------------------------------------------------------------------------
/app/twig_templates/user/entries/syntax_error.twig:
--------------------------------------------------------------------------------
1 | {{ _("Syntax Error") }}
2 |
3 | {{ _("There may be a problem with a installed plugin or template.") }}
--------------------------------------------------------------------------------
/app/twig_templates/user/layouts/default.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{ block('title') }}{% if blog.id %} - {{ blog.id }}{% endif %}
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
37 |
38 |
39 |
40 | {{ block('content') }}
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fc2blog/blog",
3 | "description": "オープンソースのブログ",
4 | "license": "MIT",
5 | "require": {
6 | "ext-mbstring": "*",
7 | "ext-gd": "*",
8 | "ext-gettext": "*",
9 | "ext-fileinfo": "*",
10 | "ext-json": "*",
11 | "ext-pdo": "*",
12 | "ext-zip": "*",
13 | "monolog/monolog": "^2.1",
14 | "league/flysystem": "^1.1",
15 | "twig/twig": "^3.0",
16 | "nikic/php-parser": "^4.10",
17 | "tuupola/base62": "^2.1",
18 | "mibe/feedwriter": "^1.1",
19 | "swiftmailer/swiftmailer": "^6.0",
20 | "maxmind-db/reader": "~1.0"
21 | },
22 | "config": {
23 | "vendor-dir": "app/vendor"
24 | },
25 | "require-dev": {
26 | "phpunit/phpunit": "^9.2",
27 | "simplepie/simplepie": "^1.5",
28 | "ramsey/uuid": "^4.1",
29 | "fakerphp/faker": "^1.13",
30 | "uzulla/pseudo_sendmail": "^1.0"
31 | },
32 | "autoload": {
33 | "psr-4": {
34 | "Fc2blog\\": "app/src/"
35 | },
36 | "files": [
37 | "app/src/include/common_functions.php"
38 | ]
39 | },
40 | "autoload-dev": {
41 | "psr-4": {
42 | "Fc2blog\\Tests\\": "tests/"
43 | }
44 | },
45 | "scripts": {
46 | "test": "phpunit"
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/dist_zip/.gitignore:
--------------------------------------------------------------------------------
1 | fc2blog_dist.zip
2 | fc2blog/
3 | test_vm/fc2blog_dist.zip
4 | test_vm/fc2blog_installer.php
5 |
--------------------------------------------------------------------------------
/dist_zip/test_vm/001-blog.conf:
--------------------------------------------------------------------------------
1 | # for development purpose.
2 |
3 | DocumentRoot /var/www/html
4 | ErrorLog /dev/stdout
5 | CustomLog /dev/stdout combined
6 |
7 |
8 | Options FollowSymlinks Includes
9 | AllowOverride All
10 | Require all granted
11 |
12 |
13 |
14 |
15 | DocumentRoot /var/www/html
16 | ErrorLog /dev/stdout
17 | CustomLog /dev/stdout combined
18 |
19 | SSLEngine on
20 | SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
21 | SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
22 |
23 |
24 | Options FollowSymlinks Includes
25 | AllowOverride All
26 | Require all granted
27 |
28 |
29 |
--------------------------------------------------------------------------------
/dist_zip/test_vm/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ubuntu:focal
2 |
3 | ENV DEBIAN_FRONTEND=noninteractive
4 |
5 | RUN set -eux \
6 | && apt-get update -y \
7 | && apt-get upgrade -y \
8 | && apt-get install -y software-properties-common iproute2 vim git wget unzip locales ssl-cert \
9 | && sed -i -E 's/# (ja_JP.UTF-8)/\1/' /etc/locale.gen \
10 | && locale-gen \
11 | && rm -rf /tmp/*
12 |
13 | RUN add-apt-repository -y ppa:ondrej/php \
14 | && add-apt-repository -y ppa:ondrej/apache2 \
15 | && apt-get update \
16 | && apt-get install -y apache2 mysql-server php8.0 libapache2-mod-php8.0 php8.0-intl php8.0-mbstring php8.0-gd php8.0-mysql php8.0-zip
17 |
18 | ARG PUID=1000
19 | ARG PGID=1000
20 |
21 | RUN groupmod -o -g $PGID www-data && \
22 | usermod -o -u $PUID -g www-data www-data && \
23 | usermod --shell /bin/bash www-data
24 |
25 | COPY 001-blog.conf /etc/apache2/sites-available/
26 |
27 | RUN make-ssl-cert generate-default-snakeoil --force-overwrite \
28 | && a2enmod rewrite \
29 | && a2enmod ssl \
30 | && a2ensite 001-blog \
31 | && a2dissite 000-default.conf \
32 | && a2dissite default-ssl.conf
33 |
34 | RUN mkdir /var/run/mysqld \
35 | && chmod 777 /var/run/mysqld
36 |
37 | RUN sh -c "/usr/bin/mysqld_safe --user=mysql &" \
38 | && sleep 3 \
39 | && mysql_secure_installation -ppass -D \
40 | && echo "CREATE DATABASE fc2blog_db" | mysql \
41 | && echo "CREATE USER 'dbuser'@'127.0.0.1' IDENTIFIED BY 'd1B2p3a#s!s';" | mysql \
42 | && echo "GRANT ALL ON fc2blog_db.* TO 'dbuser'@'127.0.0.1';" | mysql
43 |
44 | COPY fc2blog_dist.zip /var/www/html/
45 | COPY fc2blog_installer.php /var/www/html/
46 | RUN chown -R www-data:www-data /var/www/
47 |
48 | COPY startup.sh /
49 |
--------------------------------------------------------------------------------
/dist_zip/test_vm/Makefile:
--------------------------------------------------------------------------------
1 | PHONY:
2 | image:
3 | # alignment local UID/GID and docker UID/GID for Linux dev env.
4 | $(eval UID := $(shell id -u))
5 | $(eval GID := $(shell id -g))
6 | docker build -t fc2_dist_test_vm --build-arg PUID=$(UID) --build-arg PGID=$(GID) .
7 |
8 | PHONY:
9 | image-no-cache:
10 | # alignment local UID/GID and docker UID/GID for Linux dev env.
11 | $(eval UID := $(shell id -u))
12 | $(eval GID := $(shell id -g))
13 | docker build -t fc2_dist_test_vm --no-cache --build-arg PUID=$(UID) --build-arg PGID=$(GID) .
14 |
15 | PHONY:
16 | run:
17 | docker run --rm -it fc2_dist_test_vm sh -c "/startup.sh ; bash"
18 |
19 | PHONY:
20 | bash:
21 | docker run --rm -it fc2_dist_test_vm bash
22 |
23 |
--------------------------------------------------------------------------------
/dist_zip/test_vm/config.php:
--------------------------------------------------------------------------------
1 |
3 | DocumentRoot /fc2blog/public
4 | ErrorLog ${APACHE_LOG_DIR}/error.log
5 | CustomLog ${APACHE_LOG_DIR}/access.log combined
6 |
7 |
8 | Options FollowSymlinks Includes
9 | AllowOverride All
10 | Require all granted
11 |
12 |
13 |
14 |
15 | DocumentRoot /fc2blog/public
16 | ErrorLog ${APACHE_LOG_DIR}/error.log
17 | CustomLog ${APACHE_LOG_DIR}/access.log combined
18 |
19 | SSLEngine on
20 | SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
21 | SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
22 |
23 |
24 | Options FollowSymlinks Includes
25 | AllowOverride All
26 | Require all granted
27 |
28 |
29 |
--------------------------------------------------------------------------------
/docker/apache/usr/local/etc/php/conf.d/docker-php-ext-xdebug-debug-enable.ini:
--------------------------------------------------------------------------------
1 | xdebug.mode = debug
2 | xdebug.client_host = host.docker.internal
3 | xdebug.discover_client_host = On
4 | xdebug.var_display_max_children = -1
5 | xdebug.var_display_max_data = -1
6 | xdebug.var_display_max_depth = -1
7 |
--------------------------------------------------------------------------------
/docker/apache/usr/local/etc/php/conf.d/php-error-settings.ini:
--------------------------------------------------------------------------------
1 | display_errors = on
2 | display_startup_errors = On
3 | log_errors = On
4 | error_reporting = -1
5 |
--------------------------------------------------------------------------------
/docker/mysqld/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mariadb:10.5
2 |
3 | ARG PUID=1000
4 | ARG PGID=1000
5 |
6 | RUN echo "-> $PUID"
7 | RUN echo "-> $PGID"
8 |
9 | RUN groupmod -o -g $PGID mysql && \
10 | usermod -o -u $PUID -g mysql mysql && \
11 | usermod --shell /bin/bash mysql
12 |
13 | COPY mysqld.cnf /etc/mysql/mysql.conf.d/mysqld.cnf
14 |
--------------------------------------------------------------------------------
/docker/mysqld/mysqld.cnf:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
2 | #
3 | # This program is free software; you can redistribute it and/or modify
4 | # it under the terms of the GNU General Public License as published by
5 | # the Free Software Foundation; version 2 of the License.
6 | #
7 | # This program is distributed in the hope that it will be useful,
8 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 | # GNU General Public License for more details.
11 | #
12 | # You should have received a copy of the GNU General Public License
13 | # along with this program; if not, write to the Free Software
14 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15 |
16 | #
17 | # The MySQL Server configuration file.
18 | #
19 | # For explanations see
20 | # http://dev.mysql.com/doc/mysql/en/server-system-variables.html
21 |
22 | [mysqld]
23 | pid-file = /var/run/mysqld/mysqld.pid
24 | socket = /var/run/mysqld/mysqld.sock
25 | datadir = /var/lib/mysql
26 | #log-error = /var/log/mysql/error.log
27 | # By default we only accept connections from localhost
28 | #bind-address = 127.0.0.1
29 | # Disabling symbolic-links is recommended to prevent assorted security risks
30 | symbolic-links=0
31 |
32 | character-set-server=utf8mb4
33 | collation-server=utf8mb4_unicode_ci
34 |
--------------------------------------------------------------------------------
/e2e_test/.env.sample:
--------------------------------------------------------------------------------
1 | BASE_URL='https://local.test:8480'
2 | BASIC_ID=
3 | BASIC_PASS=
4 | # テストをヘッドレスでなく、表示しつつ行う
5 | NO_HEAD_LESS=0
6 | VIEW_PORT_HEIGHT=1000
7 |
--------------------------------------------------------------------------------
/e2e_test/.gitignore:
--------------------------------------------------------------------------------
1 | ss/
2 | node_modules
3 | .env
4 |
--------------------------------------------------------------------------------
/e2e_test/README.md:
--------------------------------------------------------------------------------
1 | # E2E test by puppeteer
2 |
3 | ## Setup
4 |
5 | ```
6 | $ npm ci
7 |
8 | # If you want configure
9 | $ cp .env.sample .env
10 | $ vi .env
11 | ```
12 |
13 | ## Target fc2blog setup
14 |
15 | - Start target fc2blog webapp.
16 | - Run `phpunit` for pseudo data set loading.
17 |
18 | > Recommend: use docker.
19 | >
20 | > If you run at own apache or other, Set `DEBUG_FORCE_CAPTCHA_KEY=1234` ENV.
21 |
22 |
23 | ## Execute e2e test
24 |
25 | ```
26 | # All test execution.
27 | $ npm run test
28 |
29 | # or specify a test.
30 | $ npx jest test/test.test.js
31 | ```
32 |
33 | ## Don't forget code format before test code commit.
34 |
35 | ```
36 | # format by prettier
37 | $ npm run fmt
38 | ```
39 |
40 |
--------------------------------------------------------------------------------
/e2e_test/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | [
4 | '@babel/preset-env',
5 | {
6 | 'targets': {"node": "current"},
7 | }
8 | ]
9 | ],
10 | };
--------------------------------------------------------------------------------
/e2e_test/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | preset: 'ts-jest',
3 | testEnvironment: 'node',
4 | verbose: true,
5 | testMatch: [
6 | "**/?(*.)+(spec|test).+(ts|tsx|js)"
7 | ],
8 | setupFilesAfterEnv: [
9 | `${process.cwd()}/jest.setup.js`
10 | ],
11 | "transform": {
12 | "^.+\\.(ts|tsx)$": "ts-jest"
13 | },
14 | };
15 |
--------------------------------------------------------------------------------
/e2e_test/jest.setup.js:
--------------------------------------------------------------------------------
1 | // テスト環境によっては伸ばす必要がある
2 | jest.setTimeout(60 * 1000); // 60秒でタイムアウト
3 |
--------------------------------------------------------------------------------
/e2e_test/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fc2blog_frontend_e2e_test",
3 | "version": "1.0.0",
4 | "description": "automation test with puppeteer",
5 | "repository": "https://github.com/fc2blog/blog",
6 | "author": "",
7 | "license": "MIT",
8 | "scripts": {
9 | "test": "npm run serial-test && npm run parallel-test",
10 | "php-prepare": "php ../tests/cli_load_fixture.php",
11 | "parallel-test": "npm run php-prepare && npm run clear-cache && curl -D - -s -o /dev/null http://localhost && npx jest tests/*",
12 | "serial-test": "npm run php-prepare && npm run clear-cache && npx jest --runInBand serial_execute_tests/*",
13 | "fmt": "npx prettier --check --write \"./tests/*.ts\"",
14 | "clear-cache": "npx jest --clearCache",
15 | "test-enable-head": "NO_HEAD_LESS=1 npx jest",
16 | "update-libs": "npx npm-check-updates -u"
17 | },
18 | "dependencies": {
19 | "@babel/core": "^7.12.3",
20 | "@babel/preset-env": "^7.12.1",
21 | "@jest/globals": "^26.6.1",
22 | "@types/jest": "^26.0.15",
23 | "@types/node": "^14.14.6",
24 | "@types/puppeteer": "^3.0.2",
25 | "dotenv": "^8.2.0",
26 | "jest": "^26.6.1",
27 | "puppeteer": "^5.4.1",
28 | "sprintf-js": "^1.1.2",
29 | "ts-jest": "^26.4.3",
30 | "typescript": "^3.9.7"
31 | },
32 | "devDependencies": {
33 | "npm-check-updates": "^7.1.1",
34 | "prettier": "2.0.5"
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/e2e_test/ss/.gitkeep:
--------------------------------------------------------------------------------
1 | screen shot
2 |
--------------------------------------------------------------------------------
/e2e_test/tests/admin_installer.test.ts:
--------------------------------------------------------------------------------
1 | import {afterAll, beforeAll, describe, expect, it} from "@jest/globals";
2 | import {Helper} from "./helper";
3 |
4 | describe("crawl admin pages", () => {
5 | let c: Helper;
6 |
7 | beforeAll(async () => {
8 | c = new Helper();
9 | await c.init();
10 | });
11 |
12 | const start_url = "/admin/common/install";
13 |
14 | it("open login page", async () => {
15 | const [response] = await Promise.all([
16 | c.waitLoad(),
17 | c.page.goto(c.getBaseUrl() + start_url),
18 | ]);
19 |
20 | await c.getSS("admin_install.png");
21 |
22 | expect(response.status()).toEqual(200);
23 | expect(await c.isNotAnyNoticeOrWarningsFinishWithEndHtmlTag()).toBeTruthy();
24 | });
25 |
26 | // 実際のインストール処理が正常に行えるか?は追って追記
27 | // 当座開いてエラーがでないかだけをテスト
28 |
29 | afterAll(async () => {
30 | await c.browser.close();
31 | });
32 | });
33 |
--------------------------------------------------------------------------------
/e2e_test/tests/open_base_url.test.ts:
--------------------------------------------------------------------------------
1 | import {afterAll, beforeAll, describe, it} from "@jest/globals";
2 | import {Helper} from "./helper";
3 |
4 | describe("will be redirect to random blog page", () => {
5 | let c: Helper;
6 |
7 | beforeAll(async () => {
8 | c = new Helper();
9 | await c.init();
10 | });
11 |
12 | it("redirect to random blog page", async () => {
13 | // This redirect url test cause these failure by unknown reason.
14 | // Anyway, we need CI to success now !!
15 | // I'll be restore bellow expects in the future.
16 |
17 | // const response = await c.openUrlWithNoCheck(c.getBaseUrl());
18 | // const redirect = response.request().redirectChain()[0];
19 | // expect(redirect.url()).toEqual(c.getBaseUrl() + "/");
20 | // expect(redirect.response().headers().location).toMatch(/\/testblog[0-9]\//);
21 | // expect(response.status()).toEqual(200);
22 | });
23 |
24 | it("get Title after redirected page.", async () => {
25 | // expect(await c.getTitle()).toMatch(/testblog/);
26 | });
27 |
28 | afterAll(async () => {
29 | await c.browser.close();
30 | });
31 | });
32 |
--------------------------------------------------------------------------------
/e2e_test/tests/test.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/e2e_test/tests/test.png
--------------------------------------------------------------------------------
/e2e_test/tests/test.test.ts:
--------------------------------------------------------------------------------
1 | // testのテスト
2 | test("1 = 1", () => {
3 | expect(1).toBe(1);
4 | });
5 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fc2blog",
3 | "version": "0.0.0",
4 | "description": "oss blog",
5 | "repository": "https://github.com/fc2blog/blog",
6 | "author": "",
7 | "license": "MIT",
8 | "scripts": {
9 | "copy-cookie-js": "cp node_modules/js-cookie/src/js.cookie.js public/js/"
10 | },
11 | "dependencies": {
12 | "jquery": "^3.6.0",
13 | "jquery-toggles": "^4.0.0",
14 | "jquery-ui": "^1.12.1",
15 | "jquery-ui-timepicker-addon": "^1.6.3",
16 | "js-cookie": "^2.2.1"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 | tests/
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/public/.htaccess:
--------------------------------------------------------------------------------
1 | RewriteEngine On
2 | RewriteBase /
3 | RewriteCond %{REQUEST_FILENAME} -f [OR]
4 | RewriteCond %{REQUEST_FILENAME} -d
5 | RewriteRule . - [L]
6 | RewriteRule . index.php [L]
7 |
--------------------------------------------------------------------------------
/public/assets/admin/css/sp/category_sp.css:
--------------------------------------------------------------------------------
1 | .checkbox_list label, .category_list p {
2 | display: block;
3 | padding: 10px 0 10px 5px;
4 | }
5 |
6 | .checkbox_list li, .category_list li {
7 | border-top: 1px solid #eee;
8 | }
9 |
10 | .checkbox_list li ul, .category_list li ul {
11 | margin-top: -1px;
12 | }
13 |
14 | .checkbox_list input[type="checkbox"] {
15 | visibility: visible;
16 | }
17 |
18 | .checkbox_list li li, .category_list li li {
19 | margin-left: 0.5em;
20 | padding-left: 0.5em;
21 | border-left: 2px solid #eee;
22 | }
23 |
24 | .category_list p a {
25 | color: #04c;
26 | display: block;
27 | }
28 |
--------------------------------------------------------------------------------
/public/assets/admin/css/sp/entry_sp.css:
--------------------------------------------------------------------------------
1 | #sys-add-tags > li {
2 | border: 1px solid #c8c8c8;
3 | border-radius: 5px;
4 | padding: 8px;
5 | margin: 3px;
6 | display: inline-block;
7 | background-color: #f4f4f4;
8 | box-shadow: 1px 1px 1px rgba(1, 1, 1, 0.3);
9 | }
10 |
11 | #sys-add-tags > li > span {
12 | display: inline-block;
13 | vertical-align: middle;
14 | }
15 |
16 | #add-tag-line {
17 | border: 1px solid #c8c8c8;
18 | }
19 |
20 | #sys-use-well-tags > li {
21 | border: 1px solid #c8c8c8;
22 | border-radius: 5px;
23 | padding: 8px;
24 | margin: 3px;
25 | display: inline-block;
26 | background-color: #f4f4f4;
27 | box-shadow: 1px 1px 1px rgba(1, 1, 1, 0.3);
28 | }
29 |
--------------------------------------------------------------------------------
/public/assets/admin/img/admin_icon2_02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/img/admin_icon2_02.png
--------------------------------------------------------------------------------
/public/assets/admin/img/admin_icon3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/img/admin_icon3.png
--------------------------------------------------------------------------------
/public/assets/admin/img/handle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/img/handle.png
--------------------------------------------------------------------------------
/public/assets/admin/img/sp/sp_blog_btn_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/img/sp/sp_blog_btn_icon.png
--------------------------------------------------------------------------------
/public/assets/admin/img/sp/sp_blog_btn_icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/img/sp/sp_blog_btn_icon@2x.png
--------------------------------------------------------------------------------
/public/assets/admin/img/sp/sp_blog_detail_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/img/sp/sp_blog_detail_bg.png
--------------------------------------------------------------------------------
/public/assets/admin/img/sp/sp_blog_detail_bg@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/img/sp/sp_blog_detail_bg@2x.png
--------------------------------------------------------------------------------
/public/assets/admin/img/sp/sp_blog_sidemenu_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/img/sp/sp_blog_sidemenu_bg.png
--------------------------------------------------------------------------------
/public/assets/admin/img/sp/sp_blog_sidemenu_bg@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/img/sp/sp_blog_sidemenu_bg@2x.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/css/smoothness/images/ui-icons_222222_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/css/smoothness/images/ui-icons_222222_256x240.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/css/smoothness/images/ui-icons_2e83ff_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/css/smoothness/images/ui-icons_2e83ff_256x240.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/css/smoothness/images/ui-icons_454545_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/css/smoothness/images/ui-icons_454545_256x240.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/css/smoothness/images/ui-icons_888888_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/css/smoothness/images/ui-icons_888888_256x240.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/css/smoothness/images/ui-icons_cd0a0a_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/css/smoothness/images/ui-icons_cd0a0a_256x240.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/images/elrte-toolbar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/images/elrte-toolbar.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/images/google-maps.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/images/google-maps.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/images/iframe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/images/iframe.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/images/loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/images/loading.gif
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/images/media-director.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/images/media-director.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/images/media-flash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/images/media-flash.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/images/media-quicktime.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/images/media-quicktime.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/images/media-realaudio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/images/media-realaudio.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/images/media-rutube.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/images/media-rutube.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/images/media-vimeo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/images/media-vimeo.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/images/media-winmedia.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/images/media-winmedia.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/images/media-youtube.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/images/media-youtube.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/images/outline-div.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/images/outline-div.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/images/outline-p.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/images/outline-p.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/images/pagebreak.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/images/pagebreak.gif
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/images/pixel.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/images/pixel.gif
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/images/smileys/evilgrin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/images/smileys/evilgrin.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/images/smileys/grin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/images/smileys/grin.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/images/smileys/happy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/images/smileys/happy.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/images/smileys/smile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/images/smileys/smile.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/images/smileys/surprised.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/images/smileys/surprised.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/images/smileys/tongue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/images/smileys/tongue.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/images/smileys/unhappy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/images/smileys/unhappy.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/images/smileys/waii.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/images/smileys/waii.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/images/smileys/wink.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/images/smileys/wink.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/images/yandex-maps.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/admin/js/elrte/images/yandex-maps.png
--------------------------------------------------------------------------------
/public/assets/admin/js/elrte/js/i18n/elrte.en.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This is dummy file and does nothing.
3 | *
4 | * You do not need to include it for English localization.
5 | *
6 | * Translators!
7 | * If you want to make new localization use 'elrte.YOUR_LANG.js' file
8 | * in this directory as template.
9 | * Please submit your localization by creating new issue:
10 | * http://elrte.org/redmine/projects/elrte/issues/new
11 | */
12 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-af.js:
--------------------------------------------------------------------------------
1 | /* Afrikaans translation for the jQuery Timepicker Addon */
2 | /* Written by Deon Heyns */
3 | (function($) {
4 | $.timepicker.regional['af'] = {
5 | timeOnlyTitle: 'Kies Tyd',
6 | timeText: 'Tyd ',
7 | hourText: 'Ure ',
8 | minuteText: 'Minute',
9 | secondText: 'Sekondes',
10 | millisecText: 'Millisekondes',
11 | microsecText: 'Mikrosekondes',
12 | timezoneText: 'Tydsone',
13 | currentText: 'Huidige Tyd',
14 | closeText: 'Klaar',
15 | timeFormat: 'HH:mm',
16 | amNames: ['AM', 'A'],
17 | pmNames: ['PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['af']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-am.js:
--------------------------------------------------------------------------------
1 | /* Armenian translation for the jQuery Timepicker Addon */
2 | /* Written by Artavazd Avetisyan artavazda@hotmail.com */
3 | (function($) {
4 | $.timepicker.regional['am'] = {
5 | timeOnlyTitle: 'Ընտրեք ժամանակը',
6 | timeText: 'Ժամանակը',
7 | hourText: 'Ժամ',
8 | minuteText: 'Րոպե',
9 | secondText: 'Վարկյան',
10 | millisecText: 'Միլիվարկյան',
11 | microsecText: 'Միկրովարկյան',
12 | timezoneText: 'Ժամային գոտին',
13 | currentText: 'Այժմ',
14 | closeText: 'Փակել',
15 | timeFormat: 'HH:mm',
16 | amNames: ['AM', 'A'],
17 | pmNames: ['PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['am']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-bg.js:
--------------------------------------------------------------------------------
1 | /* Bulgarian translation for the jQuery Timepicker Addon */
2 | /* Written by Plamen Kovandjiev */
3 | (function($) {
4 | $.timepicker.regional['bg'] = {
5 | timeOnlyTitle: 'Изберете време',
6 | timeText: 'Време',
7 | hourText: 'Час',
8 | minuteText: 'Минути',
9 | secondText: 'Секунди',
10 | millisecText: 'Милисекунди',
11 | microsecText: 'Микросекунди',
12 | timezoneText: 'Часови пояс',
13 | currentText: 'Сега',
14 | closeText: 'Затвори',
15 | timeFormat: 'HH:mm',
16 | amNames: ['AM', 'A'],
17 | pmNames: ['PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['bg']);
21 | })(jQuery);
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-ca.js:
--------------------------------------------------------------------------------
1 | /* Catalan translation for the jQuery Timepicker Addon */
2 | /* Written by Sergi Faber */
3 | (function($) {
4 | $.timepicker.regional['ca'] = {
5 | timeOnlyTitle: 'Escollir una hora',
6 | timeText: 'Hora',
7 | hourText: 'Hores',
8 | minuteText: 'Minuts',
9 | secondText: 'Segons',
10 | millisecText: 'Milisegons',
11 | microsecText: 'Microsegons',
12 | timezoneText: 'Fus horari',
13 | currentText: 'Ara',
14 | closeText: 'Tancar',
15 | timeFormat: 'HH:mm',
16 | amNames: ['AM', 'A'],
17 | pmNames: ['PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['ca']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-cs.js:
--------------------------------------------------------------------------------
1 | /* Czech translation for the jQuery Timepicker Addon */
2 | /* Written by Ondřej Vodáček */
3 | (function($) {
4 | $.timepicker.regional['cs'] = {
5 | timeOnlyTitle: 'Vyberte čas',
6 | timeText: 'Čas',
7 | hourText: 'Hodiny',
8 | minuteText: 'Minuty',
9 | secondText: 'Vteřiny',
10 | millisecText: 'Milisekundy',
11 | microsecText: 'Mikrosekundy',
12 | timezoneText: 'Časové pásmo',
13 | currentText: 'Nyní',
14 | closeText: 'Zavřít',
15 | timeFormat: 'HH:mm',
16 | amNames: ['dop.', 'AM', 'A'],
17 | pmNames: ['odp.', 'PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['cs']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-da.js:
--------------------------------------------------------------------------------
1 | /* Danish translation for the jQuery Timepicker Addon */
2 | /* Written by Lars H. Jensen (http://www.larshj.dk) */
3 | (function ($) {
4 | $.timepicker.regional['da'] = {
5 | timeOnlyTitle: 'Vælg tid',
6 | timeText: 'Tid',
7 | hourText: 'Time',
8 | minuteText: 'Minut',
9 | secondText: 'Sekund',
10 | millisecText: 'Millisekund',
11 | microsecText: 'Mikrosekund',
12 | timezoneText: 'Tidszone',
13 | currentText: 'Nu',
14 | closeText: 'Luk',
15 | timeFormat: 'HH:mm',
16 | amNames: ['am', 'AM', 'A'],
17 | pmNames: ['pm', 'PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['da']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-de.js:
--------------------------------------------------------------------------------
1 | /* German translation for the jQuery Timepicker Addon */
2 | /* Written by Marvin */
3 | (function($) {
4 | $.timepicker.regional['de'] = {
5 | timeOnlyTitle: 'Zeit Wählen',
6 | timeText: 'Zeit',
7 | hourText: 'Stunde',
8 | minuteText: 'Minute',
9 | secondText: 'Sekunde',
10 | millisecText: 'Millisekunde',
11 | microsecText: 'Mikrosekunde',
12 | timezoneText: 'Zeitzone',
13 | currentText: 'Jetzt',
14 | closeText: 'Fertig',
15 | timeFormat: 'HH:mm',
16 | amNames: ['vorm.', 'AM', 'A'],
17 | pmNames: ['nachm.', 'PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['de']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-el.js:
--------------------------------------------------------------------------------
1 | /* Hellenic translation for the jQuery Timepicker Addon */
2 | /* Written by Christos Pontikis */
3 | (function($) {
4 | $.timepicker.regional['el'] = {
5 | timeOnlyTitle: 'Επιλογή ώρας',
6 | timeText: 'Ώρα',
7 | hourText: 'Ώρες',
8 | minuteText: 'Λεπτά',
9 | secondText: 'Δευτερόλεπτα',
10 | millisecText: 'μιλιδευτερόλεπτο',
11 | microsecText: 'Microseconds',
12 | timezoneText: 'Ζώνη ώρας',
13 | currentText: 'Τώρα',
14 | closeText: 'Κλείσιμο',
15 | timeFormat: 'HH:mm',
16 | amNames: ['π.μ.', 'AM', 'A'],
17 | pmNames: ['μ.μ.', 'PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['el']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-es.js:
--------------------------------------------------------------------------------
1 | /* Spanish translation for the jQuery Timepicker Addon */
2 | /* Written by Ianaré Sévi */
3 | (function($) {
4 | $.timepicker.regional['es'] = {
5 | timeOnlyTitle: 'Elegir una hora',
6 | timeText: 'Hora',
7 | hourText: 'Horas',
8 | minuteText: 'Minutos',
9 | secondText: 'Segundos',
10 | millisecText: 'Milisegundos',
11 | microsecText: 'Microsegundos',
12 | timezoneText: 'Huso horario',
13 | currentText: 'Ahora',
14 | closeText: 'Cerrar',
15 | timeFormat: 'HH:mm',
16 | amNames: ['a.m.', 'AM', 'A'],
17 | pmNames: ['p.m.', 'PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['es']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-et.js:
--------------------------------------------------------------------------------
1 | /* Estonian translation for the jQuery Timepicker Addon */
2 | /* Written by Karl Sutt (karl@sutt.ee) */
3 | (function($) {
4 | $.timepicker.regional['et'] = {
5 | timeOnlyTitle: 'Vali aeg',
6 | timeText: 'Aeg',
7 | hourText: 'Tund',
8 | minuteText: 'Minut',
9 | secondText: 'Sekund',
10 | millisecText: 'Millisekundis',
11 | microsecText: 'Mikrosekundis',
12 | timezoneText: 'Ajavöönd',
13 | currentText: 'Praegu',
14 | closeText: 'Valmis',
15 | timeFormat: 'HH:mm',
16 | amNames: ['AM', 'A'],
17 | pmNames: ['PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['et']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-eu.js:
--------------------------------------------------------------------------------
1 | /* Basque trannslation for JQuery Timepicker Addon
2 | /* Translated by Xabi Fer */
3 | (function($) {
4 | $.timepicker.regional['eu'] = {
5 | timeOnlyTitle: 'Aukeratu ordua',
6 | timeText: 'Ordua',
7 | hourText: 'Orduak',
8 | minuteText: 'Minutuak',
9 | secondText: 'Segunduak',
10 | millisecText: 'Milisegunduak',
11 | microsecText: 'Mikrosegundotan',
12 | timezoneText: 'Ordu-eremua',
13 | currentText: 'Orain',
14 | closeText: 'Itxi',
15 | timeFormat: 'HH:mm',
16 | amNames: ['a.m.', 'AM', 'A'],
17 | pmNames: ['p.m.', 'PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['eu']);
21 | })(jQuery);
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-fi.js:
--------------------------------------------------------------------------------
1 | /* Finnish translation for the jQuery Timepicker Addon */
2 | /* Written by Juga Paazmaya (http://github.com/paazmaya) */
3 | (function($) {
4 | $.timepicker.regional['fi'] = {
5 | timeOnlyTitle: 'Valitse aika',
6 | timeText: 'Aika',
7 | hourText: 'Tunti',
8 | minuteText: 'Minuutti',
9 | secondText: 'Sekunti',
10 | millisecText: 'Millisekunnin',
11 | microsecText: 'Mikrosekuntia',
12 | timezoneText: 'Aikavyöhyke',
13 | currentText: 'Nyt',
14 | closeText: 'Sulje',
15 | timeFormat: 'HH:mm',
16 | amNames: ['ap.', 'AM', 'A'],
17 | pmNames: ['ip.', 'PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['fi']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-fr.js:
--------------------------------------------------------------------------------
1 | /* French translation for the jQuery Timepicker Addon */
2 | /* Written by Thomas Lété */
3 | (function($) {
4 | $.timepicker.regional['fr'] = {
5 | timeOnlyTitle: 'Choisir une heure',
6 | timeText: 'Heure',
7 | hourText: 'Heures',
8 | minuteText: 'Minutes',
9 | secondText: 'Secondes',
10 | millisecText: 'Millisecondes',
11 | microsecText: 'Microsecondes',
12 | timezoneText: 'Fuseau horaire',
13 | currentText: 'Maintenant',
14 | closeText: 'Terminé',
15 | timeFormat: 'HH:mm',
16 | amNames: ['AM', 'A'],
17 | pmNames: ['PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['fr']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-gl.js:
--------------------------------------------------------------------------------
1 | /* Galician translation for the jQuery Timepicker Addon */
2 | /* Written by David Barral */
3 | (function($) {
4 | $.timepicker.regional['gl'] = {
5 | timeOnlyTitle: 'Elixir unha hora',
6 | timeText: 'Hora',
7 | hourText: 'Horas',
8 | minuteText: 'Minutos',
9 | secondText: 'Segundos',
10 | millisecText: 'Milisegundos',
11 | microsecText: 'Microssegundos',
12 | timezoneText: 'Fuso horario',
13 | currentText: 'Agora',
14 | closeText: 'Pechar',
15 | timeFormat: 'HH:mm',
16 | amNames: ['a.m.', 'AM', 'A'],
17 | pmNames: ['p.m.', 'PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['gl']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-he.js:
--------------------------------------------------------------------------------
1 | /* Hebrew translation for the jQuery Timepicker Addon */
2 | /* Written by Lior Lapid */
3 | (function($) {
4 | $.timepicker.regional["he"] = {
5 | timeOnlyTitle: "בחירת זמן",
6 | timeText: "שעה",
7 | hourText: "שעות",
8 | minuteText: "דקות",
9 | secondText: "שניות",
10 | millisecText: "אלפית השנייה",
11 | microsecText: "מיקרו",
12 | timezoneText: "אזור זמן",
13 | currentText: "עכשיו",
14 | closeText:"סגור",
15 | timeFormat: "HH:mm",
16 | amNames: ['לפנה"צ', 'AM', 'A'],
17 | pmNames: ['אחה"צ', 'PM', 'P'],
18 | isRTL: true
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional["he"]);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-hr.js:
--------------------------------------------------------------------------------
1 | /* Croatian translation for the jQuery Timepicker Addon */
2 | /* Written by Mladen */
3 | (function($) {
4 | $.timepicker.regional['hr'] = {
5 | timeOnlyTitle: 'Odaberi vrijeme',
6 | timeText: 'Vrijeme',
7 | hourText: 'Sati',
8 | minuteText: 'Minute',
9 | secondText: 'Sekunde',
10 | millisecText: 'Milisekunde',
11 | microsecText: 'Mikrosekunde',
12 | timezoneText: 'Vremenska zona',
13 | currentText: 'Sada',
14 | closeText: 'Gotovo',
15 | timeFormat: 'HH:mm',
16 | amNames: ['a.m.', 'AM', 'A'],
17 | pmNames: ['p.m.', 'PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['hr']);
21 | })(jQuery);
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-hu.js:
--------------------------------------------------------------------------------
1 | /* Hungarian translation for the jQuery Timepicker Addon */
2 | /* Written by Vas Gábor */
3 | (function($) {
4 | $.timepicker.regional['hu'] = {
5 | timeOnlyTitle: 'Válasszon időpontot',
6 | timeText: 'Idő',
7 | hourText: 'Óra',
8 | minuteText: 'Perc',
9 | secondText: 'Másodperc',
10 | millisecText: 'Milliszekundumos',
11 | microsecText: 'Ezredmásodperc',
12 | timezoneText: 'Időzóna',
13 | currentText: 'Most',
14 | closeText: 'Kész',
15 | timeFormat: 'HH:mm',
16 | amNames: ['de.', 'AM', 'A'],
17 | pmNames: ['du.', 'PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['hu']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-id.js:
--------------------------------------------------------------------------------
1 | /* Indonesian translation for the jQuery Timepicker Addon */
2 | /* Written by Nia */
3 | (function($) {
4 | $.timepicker.regional['id'] = {
5 | timeOnlyTitle: 'Pilih Waktu',
6 | timeText: 'Waktu',
7 | hourText: 'Pukul',
8 | minuteText: 'Menit',
9 | secondText: 'Detik',
10 | millisecText: 'Milidetik',
11 | microsecText: 'Mikrodetik',
12 | timezoneText: 'Zona Waktu',
13 | currentText: 'Sekarang',
14 | closeText: 'OK',
15 | timeFormat: 'HH:mm',
16 | amNames: ['AM', 'A'],
17 | pmNames: ['PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['id']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-it.js:
--------------------------------------------------------------------------------
1 | /* Italian translation for the jQuery Timepicker Addon */
2 | /* Written by Marco "logicoder" Del Tongo */
3 | (function($) {
4 | $.timepicker.regional['it'] = {
5 | timeOnlyTitle: 'Scegli orario',
6 | timeText: 'Orario',
7 | hourText: 'Ora',
8 | minuteText: 'Minuti',
9 | secondText: 'Secondi',
10 | millisecText: 'Millisecondi',
11 | microsecText: 'Microsecondi',
12 | timezoneText: 'Fuso orario',
13 | currentText: 'Adesso',
14 | closeText: 'Chiudi',
15 | timeFormat: 'HH:mm',
16 | amNames: ['m.', 'AM', 'A'],
17 | pmNames: ['p.', 'PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['it']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-ja.js:
--------------------------------------------------------------------------------
1 | /* Japanese translation for the jQuery Timepicker Addon */
2 | /* Written by Jun Omae */
3 | (function($) {
4 | $.timepicker.regional['ja'] = {
5 | timeOnlyTitle: '時間を選択',
6 | timeText: '時間',
7 | hourText: '時',
8 | minuteText: '分',
9 | secondText: '秒',
10 | millisecText: 'ミリ秒',
11 | microsecText: 'マイクロ秒',
12 | timezoneText: 'タイムゾーン',
13 | currentText: '現時刻',
14 | closeText: '閉じる',
15 | timeFormat: 'HH:mm',
16 | amNames: ['午前', 'AM', 'A'],
17 | pmNames: ['午後', 'PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['ja']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-ko.js:
--------------------------------------------------------------------------------
1 | /* Korean translation for the jQuery Timepicker Addon */
2 | /* Written by Genie */
3 | (function($) {
4 | $.timepicker.regional['ko'] = {
5 | timeOnlyTitle: '시간 선택',
6 | timeText: '시간',
7 | hourText: '시',
8 | minuteText: '분',
9 | secondText: '초',
10 | millisecText: '밀리초',
11 | microsecText: '마이크로',
12 | timezoneText: '표준 시간대',
13 | currentText: '현재 시각',
14 | closeText: '닫기',
15 | timeFormat: 'tt h:mm',
16 | amNames: ['오전', 'AM', 'A'],
17 | pmNames: ['오후', 'PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['ko']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-lt.js:
--------------------------------------------------------------------------------
1 | /* Lithuanian translation for the jQuery Timepicker Addon */
2 | /* Written by Irmantas Šiupšinskas */
3 | (function($) {
4 | $.timepicker.regional['lt'] = {
5 | timeOnlyTitle: 'Pasirinkite laiką',
6 | timeText: 'Laikas',
7 | hourText: 'Valandos',
8 | minuteText: 'Minutės',
9 | secondText: 'Sekundės',
10 | millisecText: 'Milisekundės',
11 | microsecText: 'Mikrosekundės',
12 | timezoneText: 'Laiko zona',
13 | currentText: 'Dabar',
14 | closeText: 'Uždaryti',
15 | timeFormat: 'HH:mm',
16 | amNames: ['priešpiet', 'AM', 'A'],
17 | pmNames: ['popiet', 'PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['lt']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-nl.js:
--------------------------------------------------------------------------------
1 | /* Dutch translation for the jQuery Timepicker Addon */
2 | /* Written by Martijn van der Lee */
3 | (function($) {
4 | $.timepicker.regional['nl'] = {
5 | timeOnlyTitle: 'Tijdstip',
6 | timeText: 'Tijd',
7 | hourText: 'Uur',
8 | minuteText: 'Minuut',
9 | secondText: 'Seconde',
10 | millisecText: 'Milliseconde',
11 | microsecText: 'Microseconde',
12 | timezoneText: 'Tijdzone',
13 | currentText: 'Vandaag',
14 | closeText: 'Sluiten',
15 | timeFormat: 'HH:mm',
16 | amNames: ['AM', 'A'],
17 | pmNames: ['PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['nl']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-no.js:
--------------------------------------------------------------------------------
1 | /* Norwegian translation for the jQuery Timepicker Addon */
2 | /* Written by Morten Hauan (http://hauan.me) */
3 | (function($) {
4 | $.timepicker.regional['no'] = {
5 | timeOnlyTitle: 'Velg tid',
6 | timeText: 'Tid',
7 | hourText: 'Time',
8 | minuteText: 'Minutt',
9 | secondText: 'Sekund',
10 | millisecText: 'Millisekund',
11 | microsecText: 'mikrosekund',
12 | timezoneText: 'Tidssone',
13 | currentText: 'Nå',
14 | closeText: 'Lukk',
15 | timeFormat: 'HH:mm',
16 | amNames: ['am', 'AM', 'A'],
17 | pmNames: ['pm', 'PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['no']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-pl.js:
--------------------------------------------------------------------------------
1 | /* Polish translation for the jQuery Timepicker Addon */
2 | /* Written by Michał Pena */
3 | (function($) {
4 | $.timepicker.regional['pl'] = {
5 | timeOnlyTitle: 'Wybierz godzinę',
6 | timeText: 'Czas',
7 | hourText: 'Godzina',
8 | minuteText: 'Minuta',
9 | secondText: 'Sekunda',
10 | millisecText: 'Milisekunda',
11 | microsecText: 'Mikrosekunda',
12 | timezoneText: 'Strefa czasowa',
13 | currentText: 'Teraz',
14 | closeText: 'Gotowe',
15 | timeFormat: 'HH:mm',
16 | amNames: ['AM', 'A'],
17 | pmNames: ['PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['pl']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-pt-BR.js:
--------------------------------------------------------------------------------
1 | /* Brazilian Portuguese translation for the jQuery Timepicker Addon */
2 | /* Written by Diogo Damiani (diogodamiani@gmail.com) */
3 | (function ($) {
4 | $.timepicker.regional['pt-BR'] = {
5 | timeOnlyTitle: 'Escolha o horário',
6 | timeText: 'Horário',
7 | hourText: 'Hora',
8 | minuteText: 'Minutos',
9 | secondText: 'Segundos',
10 | millisecText: 'Milissegundos',
11 | microsecText: 'Microssegundos',
12 | timezoneText: 'Fuso horário',
13 | currentText: 'Agora',
14 | closeText: 'Fechar',
15 | timeFormat: 'HH:mm',
16 | amNames: ['a.m.', 'AM', 'A'],
17 | pmNames: ['p.m.', 'PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['pt-BR']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-pt.js:
--------------------------------------------------------------------------------
1 | /* Portuguese translation for the jQuery Timepicker Addon */
2 | /* Written by Luan Almeida */
3 | (function($) {
4 | $.timepicker.regional['pt'] = {
5 | timeOnlyTitle: 'Escolha uma hora',
6 | timeText: 'Hora',
7 | hourText: 'Horas',
8 | minuteText: 'Minutos',
9 | secondText: 'Segundos',
10 | millisecText: 'Milissegundos',
11 | microsecText: 'Microssegundos',
12 | timezoneText: 'Fuso horário',
13 | currentText: 'Agora',
14 | closeText: 'Fechar',
15 | timeFormat: 'HH:mm',
16 | amNames: ['a.m.', 'AM', 'A'],
17 | pmNames: ['p.m.', 'PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['pt']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-ro.js:
--------------------------------------------------------------------------------
1 | /* Romanian translation for the jQuery Timepicker Addon */
2 | /* Written by Romeo Adrian Cioaba */
3 | (function($) {
4 | $.timepicker.regional['ro'] = {
5 | timeOnlyTitle: 'Alegeţi o oră',
6 | timeText: 'Timp',
7 | hourText: 'Ore',
8 | minuteText: 'Minute',
9 | secondText: 'Secunde',
10 | millisecText: 'Milisecunde',
11 | microsecText: 'Microsecunde',
12 | timezoneText: 'Fus orar',
13 | currentText: 'Acum',
14 | closeText: 'Închide',
15 | timeFormat: 'HH:mm',
16 | amNames: ['AM', 'A'],
17 | pmNames: ['PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['ro']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-ru.js:
--------------------------------------------------------------------------------
1 | /* Russian translation for the jQuery Timepicker Addon */
2 | /* Written by Trent Richardson */
3 | (function($) {
4 | $.timepicker.regional['ru'] = {
5 | timeOnlyTitle: 'Выберите время',
6 | timeText: 'Время',
7 | hourText: 'Часы',
8 | minuteText: 'Минуты',
9 | secondText: 'Секунды',
10 | millisecText: 'Миллисекунды',
11 | microsecText: 'Микросекунды',
12 | timezoneText: 'Часовой пояс',
13 | currentText: 'Сейчас',
14 | closeText: 'Закрыть',
15 | timeFormat: 'HH:mm',
16 | amNames: ['AM', 'A'],
17 | pmNames: ['PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['ru']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-sk.js:
--------------------------------------------------------------------------------
1 | /* Slovak translation for the jQuery Timepicker Addon */
2 | /* Written by David Vallner */
3 | (function($) {
4 | $.timepicker.regional['sk'] = {
5 | timeOnlyTitle: 'Zvoľte čas',
6 | timeText: 'Čas',
7 | hourText: 'Hodiny',
8 | minuteText: 'Minúty',
9 | secondText: 'Sekundy',
10 | millisecText: 'Milisekundy',
11 | microsecText: 'Mikrosekundy',
12 | timezoneText: 'Časové pásmo',
13 | currentText: 'Teraz',
14 | closeText: 'Zavrieť',
15 | timeFormat: 'H:m',
16 | amNames: ['dop.', 'AM', 'A'],
17 | pmNames: ['pop.', 'PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['sk']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-sr-RS.js:
--------------------------------------------------------------------------------
1 | /* Serbian cyrilic translation for the jQuery Timepicker Addon */
2 | /* Written by Vladimir Jelovac */
3 | (function($) {
4 | $.timepicker.regional['sr-RS'] = {
5 | timeOnlyTitle: 'Одаберите време',
6 | timeText: 'Време',
7 | hourText: 'Сати',
8 | minuteText: 'Минути',
9 | secondText: 'Секунде',
10 | millisecText: 'Милисекунде',
11 | microsecText: 'Микросекунде',
12 | timezoneText: 'Временска зона',
13 | currentText: 'Сада',
14 | closeText: 'Затвори',
15 | timeFormat: 'HH:mm',
16 | amNames: ['AM', 'A'],
17 | pmNames: ['PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['sr-RS']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-sr-YU.js:
--------------------------------------------------------------------------------
1 | /* Serbian latin translation for the jQuery Timepicker Addon */
2 | /* Written by Vladimir Jelovac */
3 | (function($) {
4 | $.timepicker.regional['sr-YU'] = {
5 | timeOnlyTitle: 'Odaberite vreme',
6 | timeText: 'Vreme',
7 | hourText: 'Sati',
8 | minuteText: 'Minuti',
9 | secondText: 'Sekunde',
10 | millisecText: 'Milisekunde',
11 | microsecText: 'Mikrosekunde',
12 | timezoneText: 'Vremenska zona',
13 | currentText: 'Sada',
14 | closeText: 'Zatvori',
15 | timeFormat: 'HH:mm',
16 | amNames: ['AM', 'A'],
17 | pmNames: ['PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['sr-YU']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-sv.js:
--------------------------------------------------------------------------------
1 | /* Swedish translation for the jQuery Timepicker Addon */
2 | /* Written by Nevon */
3 | (function($) {
4 | $.timepicker.regional['sv'] = {
5 | timeOnlyTitle: 'Välj en tid',
6 | timeText: 'Tid',
7 | hourText: 'Timme',
8 | minuteText: 'Minut',
9 | secondText: 'Sekund',
10 | millisecText: 'Millisekund',
11 | microsecText: 'Mikrosekund',
12 | timezoneText: 'Tidszon',
13 | currentText: 'Nu',
14 | closeText: 'Stäng',
15 | timeFormat: 'HH:mm',
16 | amNames: ['AM', 'A'],
17 | pmNames: ['PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['sv']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-th.js:
--------------------------------------------------------------------------------
1 | /* Thai translation for the jQuery Timepicker Addon */
2 | /* Written by Yote Wachirapornpongsa */
3 | (function($) {
4 | $.timepicker.regional['th'] = {
5 | timeOnlyTitle: 'เลือกเวลา',
6 | timeText: 'เวลา ',
7 | hourText: 'ชั่วโมง ',
8 | minuteText: 'นาที',
9 | secondText: 'วินาที',
10 | millisecText: 'มิลลิวินาที',
11 | microsecText: 'ไมโคริวินาที',
12 | timezoneText: 'เขตเวลา',
13 | currentText: 'เวลาปัจจุบัน',
14 | closeText: 'ปิด',
15 | timeFormat: 'hh:mm tt'
16 | };
17 | $.timepicker.setDefaults($.timepicker.regional['th']);
18 | })(jQuery);
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-tr.js:
--------------------------------------------------------------------------------
1 | /* Turkish translation for the jQuery Timepicker Addon */
2 | /* Written by Fehmi Can Saglam, Edited by Goktug Ozturk */
3 | (function($) {
4 | $.timepicker.regional['tr'] = {
5 | timeOnlyTitle: 'Zaman Seçiniz',
6 | timeText: 'Zaman',
7 | hourText: 'Saat',
8 | minuteText: 'Dakika',
9 | secondText: 'Saniye',
10 | millisecText: 'Milisaniye',
11 | microsecText: 'Mikrosaniye',
12 | timezoneText: 'Zaman Dilimi',
13 | currentText: 'Şu an',
14 | closeText: 'Tamam',
15 | timeFormat: 'HH:mm',
16 | amNames: ['ÖÖ', 'Ö'],
17 | pmNames: ['ÖS', 'S'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['tr']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-uk.js:
--------------------------------------------------------------------------------
1 | /* Ukrainian translation for the jQuery Timepicker Addon */
2 | /* Written by Sergey Noskov */
3 | (function($) {
4 | $.timepicker.regional['uk'] = {
5 | timeOnlyTitle: 'Виберіть час',
6 | timeText: 'Час',
7 | hourText: 'Години',
8 | minuteText: 'Хвилини',
9 | secondText: 'Секунди',
10 | millisecText: 'Мілісекунди',
11 | microsecText: 'Мікросекунди',
12 | timezoneText: 'Часовий пояс',
13 | currentText: 'Зараз',
14 | closeText: 'Закрити',
15 | timeFormat: 'HH:mm',
16 | amNames: ['AM', 'A'],
17 | pmNames: ['PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['uk']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-vi.js:
--------------------------------------------------------------------------------
1 | /* Vietnamese translation for the jQuery Timepicker Addon */
2 | /* Written by Nguyen Dinh Trung */
3 | (function($) {
4 | $.timepicker.regional['vi'] = {
5 | timeOnlyTitle: 'Chọn giờ',
6 | timeText: 'Thời gian',
7 | hourText: 'Giờ',
8 | minuteText: 'Phút',
9 | secondText: 'Giây',
10 | millisecText: 'Phần nghìn giây',
11 | microsecText: 'Miligiây',
12 | timezoneText: 'Múi giờ',
13 | currentText: 'Hiện thời',
14 | closeText: 'Đóng',
15 | timeFormat: 'H:m',
16 | amNames: ['SA', 'AM', 'A'],
17 | pmNames: ['CH', 'PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['vi']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-zh-CN.js:
--------------------------------------------------------------------------------
1 | /* Simplified Chinese translation for the jQuery Timepicker Addon /
2 | / Written by Will Lu */
3 | (function($) {
4 | $.timepicker.regional['zh-CN'] = {
5 | timeOnlyTitle: '选择时间',
6 | timeText: '时间',
7 | hourText: '小时',
8 | minuteText: '分钟',
9 | secondText: '秒钟',
10 | millisecText: '微秒',
11 | microsecText: '微秒',
12 | timezoneText: '时区',
13 | currentText: '现在时间',
14 | closeText: '关闭',
15 | timeFormat: 'HH:mm',
16 | amNames: ['AM', 'A'],
17 | pmNames: ['PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['zh-CN']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/i18n/jquery-ui-timepicker-zh-TW.js:
--------------------------------------------------------------------------------
1 | /* Chinese translation for the jQuery Timepicker Addon */
2 | /* Written by Alang.lin */
3 | (function($) {
4 | $.timepicker.regional['zh-TW'] = {
5 | timeOnlyTitle: '選擇時分秒',
6 | timeText: '時間',
7 | hourText: '時',
8 | minuteText: '分',
9 | secondText: '秒',
10 | millisecText: '毫秒',
11 | microsecText: '微秒',
12 | timezoneText: '時區',
13 | currentText: '現在時間',
14 | closeText: '確定',
15 | timeFormat: 'HH:mm',
16 | amNames: ['上午', 'AM', 'A'],
17 | pmNames: ['下午', 'PM', 'P'],
18 | isRTL: false
19 | };
20 | $.timepicker.setDefaults($.timepicker.regional['zh-TW']);
21 | })(jQuery);
22 |
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery-timepicker-addons/jquery-ui-timepicker-addon.css:
--------------------------------------------------------------------------------
1 | .ui-timepicker-div .ui-widget-header { margin-bottom: 8px; }
2 | .ui-timepicker-div dl { text-align: left; }
3 | .ui-timepicker-div dl dt { float: left; clear:left; padding: 0 0 0 5px; }
4 | .ui-timepicker-div dl dd { margin: 0 10px 10px 40%; }
5 | .ui-timepicker-div td { font-size: 90%; }
6 | .ui-tpicker-grid-label { background: none; border: none; margin: 0; padding: 0; }
7 |
8 | .ui-timepicker-rtl{ direction: rtl; }
9 | .ui-timepicker-rtl dl { text-align: right; padding: 0 5px 0 0; }
10 | .ui-timepicker-rtl dl dt{ float: right; clear: right; }
11 | .ui-timepicker-rtl dl dd { margin: 0 40% 10px 10px; }
--------------------------------------------------------------------------------
/public/assets/admin/js/jquery/jquery.fc2tab.js:
--------------------------------------------------------------------------------
1 | /**
2 | * jQuery tab menu
3 | * http://fc2.com/
4 | *
5 | * Copyright 1999-2013 FC2 inc.
6 | * Author smith
7 | * ver 0.1.1 Aug 2013
8 | */
9 | (function($) {
10 | $.extend({
11 | fc2Tab: function(config) {
12 | var defaults = {
13 | menu: '.tab-menu',
14 | contents: '.tab-contents',
15 | classSelected: 'tab-selected',
16 | init: function() {
17 | $(options.menu).click(options.click);
18 | },
19 | click: function(event) {
20 | var index = $(options.menu).index(this);
21 | $(options.menu).removeClass(options.classSelected).eq(index).addClass(options.classSelected);
22 | $(options.contents).hide().eq(index).show();
23 | }
24 | };
25 | var options = $.extend({}, defaults, config);
26 | options.init();
27 | }
28 | });
29 | })(jQuery);
30 |
--------------------------------------------------------------------------------
/public/assets/admin/js/search_form.js:
--------------------------------------------------------------------------------
1 | $(function(){
2 | // ページ件数 or ページ数を変更した際に自動でサブミット
3 | $('select[name=limit]').on('change', function(){
4 | $('input[name=limit]').val($(this).val());
5 | $('#sys-search-form').submit();
6 | });
7 | // ページ数初期化有無フラグ
8 | var isPageChange = false
9 | $('select[name=page]').on('change', function(){
10 | $('input[name=page]').val($(this).val());
11 | isPageChange = true;
12 | $('#sys-search-form').submit();
13 | });
14 | // ページ数変更以外からのsubmitはページ数を初期化する
15 | $('#sys-search-form').submit(function(){
16 | if (isPageChange==false) {
17 | $('input[name=page]').val(0);
18 | }
19 | });
20 | });
21 | // 順序変更用関数
22 | function orderChange(order){
23 | var now = $('input[name=order]').val();
24 | // 現在の順序と同じ場合はdescとascを逆順に変更する
25 | if (now==order) {
26 | var matches = order.match('^(.*?)([^_]+)$');
27 | if (matches && matches.length==3){
28 | order = matches[1] + (matches[2]=='desc' ? 'asc' : 'desc')
29 | }
30 | }
31 | $('input[name=order]').val(order);
32 | $('#sys-search-form').submit();
33 | }
34 |
--------------------------------------------------------------------------------
/public/assets/admin/js/sp/jquery.accordion.js:
--------------------------------------------------------------------------------
1 | /**
2 | * jQuery fc2Accordion
3 | * http://fc2.com/
4 | *
5 | * Copyright 1999-2013 FC2 inc.
6 | * Author smith
7 | * ver 0.1.1 Aug 2013
8 | *
9 | */
10 | (function($) {
11 | $.fn.fc2Accordion = function(config) {
12 | var defaults = {
13 | contents: '.accordion_contents',
14 | classOpen: 'open',
15 | toggle: function(event) {
16 | var isOpen = $(this).hasClass(options.classOpen);
17 | $(this).toggleClass(options.classOpen, !isOpen);
18 | $(options.contents).eq(event.data.index).toggle(!isOpen);
19 | }
20 | };
21 |
22 | var options = $.extend(defaults, config);
23 |
24 | return this.each(function(i) {
25 | $(this).bind('click', {'index': i}, options.toggle);
26 | });
27 | };
28 | })(jQuery);
--------------------------------------------------------------------------------
/public/assets/admin/js/sp/jquery.fc2tab.js:
--------------------------------------------------------------------------------
1 | /**
2 | * jQuery tab menu
3 | * http://fc2.com/
4 | *
5 | * Copyright 1999-2013 FC2 inc.
6 | * Author smith
7 | * ver 0.1.1 Aug 2013
8 | */
9 | (function($) {
10 | $.extend({
11 | fc2Tab: function(config) {
12 | var defaults = {
13 | menu: '.tab-menu',
14 | contents: '.tab-contents',
15 | classSelected: 'tab-selected',
16 | init: function() {
17 | $(options.menu).click(options.click);
18 | },
19 | click: function(event) {
20 | var index = $(options.menu).index(this);
21 | $(options.menu).removeClass(options.classSelected).eq(index).addClass(options.classSelected);
22 | $(options.contents).hide().eq(index).show();
23 | }
24 | };
25 | var options = $.extend({}, defaults, config);
26 | options.init();
27 | }
28 | });
29 | })(jQuery);
--------------------------------------------------------------------------------
/public/assets/img/private_lock_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/img/private_lock_icon.png
--------------------------------------------------------------------------------
/public/assets/js/jquery-ui/images/ui-bg_diagonals-thick_18_b81900_40x40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/js/jquery-ui/images/ui-bg_diagonals-thick_18_b81900_40x40.png
--------------------------------------------------------------------------------
/public/assets/js/jquery-ui/images/ui-bg_diagonals-thick_20_666666_40x40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/js/jquery-ui/images/ui-bg_diagonals-thick_20_666666_40x40.png
--------------------------------------------------------------------------------
/public/assets/js/jquery-ui/images/ui-bg_flat_10_000000_40x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/js/jquery-ui/images/ui-bg_flat_10_000000_40x100.png
--------------------------------------------------------------------------------
/public/assets/js/jquery-ui/images/ui-bg_glass_100_f6f6f6_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/js/jquery-ui/images/ui-bg_glass_100_f6f6f6_1x400.png
--------------------------------------------------------------------------------
/public/assets/js/jquery-ui/images/ui-bg_glass_100_fdf5ce_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/js/jquery-ui/images/ui-bg_glass_100_fdf5ce_1x400.png
--------------------------------------------------------------------------------
/public/assets/js/jquery-ui/images/ui-bg_glass_65_ffffff_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/js/jquery-ui/images/ui-bg_glass_65_ffffff_1x400.png
--------------------------------------------------------------------------------
/public/assets/js/jquery-ui/images/ui-bg_gloss-wave_35_f6a828_500x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/js/jquery-ui/images/ui-bg_gloss-wave_35_f6a828_500x100.png
--------------------------------------------------------------------------------
/public/assets/js/jquery-ui/images/ui-bg_highlight-soft_100_eeeeee_1x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/js/jquery-ui/images/ui-bg_highlight-soft_100_eeeeee_1x100.png
--------------------------------------------------------------------------------
/public/assets/js/jquery-ui/images/ui-bg_highlight-soft_75_ffe45c_1x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/js/jquery-ui/images/ui-bg_highlight-soft_75_ffe45c_1x100.png
--------------------------------------------------------------------------------
/public/assets/js/jquery-ui/images/ui-icons_222222_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/js/jquery-ui/images/ui-icons_222222_256x240.png
--------------------------------------------------------------------------------
/public/assets/js/jquery-ui/images/ui-icons_228ef1_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/js/jquery-ui/images/ui-icons_228ef1_256x240.png
--------------------------------------------------------------------------------
/public/assets/js/jquery-ui/images/ui-icons_444444_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/js/jquery-ui/images/ui-icons_444444_256x240.png
--------------------------------------------------------------------------------
/public/assets/js/jquery-ui/images/ui-icons_555555_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/js/jquery-ui/images/ui-icons_555555_256x240.png
--------------------------------------------------------------------------------
/public/assets/js/jquery-ui/images/ui-icons_777620_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/js/jquery-ui/images/ui-icons_777620_256x240.png
--------------------------------------------------------------------------------
/public/assets/js/jquery-ui/images/ui-icons_777777_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/js/jquery-ui/images/ui-icons_777777_256x240.png
--------------------------------------------------------------------------------
/public/assets/js/jquery-ui/images/ui-icons_cc0000_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/js/jquery-ui/images/ui-icons_cc0000_256x240.png
--------------------------------------------------------------------------------
/public/assets/js/jquery-ui/images/ui-icons_ef8c08_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/js/jquery-ui/images/ui-icons_ef8c08_256x240.png
--------------------------------------------------------------------------------
/public/assets/js/jquery-ui/images/ui-icons_ffd27a_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/js/jquery-ui/images/ui-icons_ffd27a_256x240.png
--------------------------------------------------------------------------------
/public/assets/js/jquery-ui/images/ui-icons_ffffff_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fc2blog/blog/41afcec87579feb18b9d858da96263f902880eed/public/assets/js/jquery-ui/images/ui-icons_ffffff_256x240.png
--------------------------------------------------------------------------------
/public/assets/js/jquery-ui/jquery.ui.touch-punch.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * jQuery UI Touch Punch 0.2.3
3 | *
4 | * Copyright 2011–2014, Dave Furfero
5 | * Dual licensed under the MIT or GPL Version 2 licenses.
6 | *
7 | * Depends:
8 | * jquery.ui.widget.js
9 | * jquery.ui.mouse.js
10 | */
11 | !function(a){function f(a,b){if(!(a.originalEvent.touches.length>1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery);
--------------------------------------------------------------------------------
/public/index.php:
--------------------------------------------------------------------------------
1 | ${DIR_LIST}/LC_MESSAGES/messages.mo"
10 | msgfmt -o ${SELF_DIR}/../app/locale/${DIR_LIST}/LC_MESSAGES/messages.mo ${SELF_DIR}/../app/locale/${DIR_LIST}/LC_MESSAGES/messages.po
11 | fi
12 | done
13 | echo " ===== End convert mo file ===== "
14 |
--------------------------------------------------------------------------------
/tests/App/Controller/Admin/BlogTemplates/IndexTest.php:
--------------------------------------------------------------------------------
1 | resetSession();
27 | $this->resetCookie();
28 | $this->mergeAdminSession();
29 |
30 | $c = $this->reqGet("/admin/blog_templates/index");
31 | $this->assertInstanceOf(BlogTemplatesController::class, $c);
32 | $this->assertEquals('index', $c->getResolvedMethod());
33 |
34 | $d = $c->getData();
35 | // var_export($d);
36 |
37 | $this->assertCount(2, $d['template_ids']);
38 | $this->assertCount(2, $d['device_blog_templates']);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/tests/App/Controller/Admin/BlogTemplates/PreviewTest.php:
--------------------------------------------------------------------------------
1 | resetSession();
27 | $this->resetCookie();
28 | $this->mergeAdminSession();
29 |
30 | $c = $this->reqGet("/testblog2/index.php?mode=entries&process=preview&template_id=1&pc=1");
31 | // var_dump($c);
32 | $this->assertInstanceOf(EntriesController::class, $c);
33 | $this->assertEquals('preview', $c->getResolvedMethod());
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/tests/App/Controller/Admin/Blogs/ChoiceTest.php:
--------------------------------------------------------------------------------
1 | resetSession();
20 | $this->resetCookie();
21 | $this->mergeAdminSession();
22 |
23 | // Ja表記を確認
24 | $c = $this->reqGet("/admin/common/notice");
25 | $this->assertStringContainsString("testblog2", $c->getOutput());
26 | $this->assertEquals("testblog2", $this->clientTraitSession['blog_id']);
27 | }
28 |
29 | public function testChangeSelectedBlog(): void
30 | {
31 | $this->mergeAdminSession();
32 | $this->assertEquals("testblog2", $this->clientTraitSession['blog_id']);
33 |
34 | $r = $this->reqGetBeRedirect("/admin/blogs/choice", ['blog_id' => 'testblog1']);
35 | $this->assertEquals('/admin/', $r->redirectUrl);
36 | $this->assertEquals("testblog1", $this->clientTraitSession['blog_id']);
37 | }
38 |
39 | public function testCreateNewBlog(): void
40 | {
41 | $this->mergeAdminSession();
42 | $this->assertEquals("testblog2", $this->clientTraitSession['blog_id']);
43 |
44 | $c = $this->reqGet("/admin/blogs/create");
45 | $this->assertInstanceOf(BlogsController::class, $c);
46 | $this->assertEquals('create', $c->getResolvedMethod());
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/tests/App/Controller/Admin/Blogs/DeleteTest.php:
--------------------------------------------------------------------------------
1 | resetSession();
21 | $this->resetCookie();
22 | $this->mergeAdminSession();
23 |
24 | $c = $this->reqGet("/admin/blogs/delete");
25 | $this->assertInstanceOf(BlogsController::class, $c);
26 | $this->assertEquals("delete", $c->getResolvedMethod());
27 | }
28 |
29 | public function testDelete(): void
30 | {
31 | DBHelper::clearDbAndInsertFixture();
32 | Session::destroy(new Request());
33 | $this->resetSession();
34 | $this->resetCookie();
35 | $this->mergeAdminSession();
36 | $sig = $this->getSig();
37 |
38 | $request_data = [
39 | 'blog' => [
40 | 'delete' => '1',
41 | ],
42 | 'sig' => $sig
43 | ];
44 |
45 | $r = $this->reqPostBeRedirect("/admin/blogs/delete", $request_data);
46 | $this->assertEquals('/admin/blogs/index', $r->redirectUrl);
47 |
48 | $c = $this->reqGet("/admin/blogs/index");
49 | $this->assertStringContainsString('testblog1', $c->getOutput());
50 | $this->assertStringNotContainsString('testblog2', $c->getOutput());
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/tests/App/Controller/Admin/Common/NoticeTest.php:
--------------------------------------------------------------------------------
1 | resetSession();
27 | $this->resetCookie();
28 | $this->mergeAdminSession();
29 |
30 | $c = $this->reqGet("/admin/common/notice");
31 | $this->assertEquals(0, $c->get("unread_count"));
32 | $this->assertEquals(0, $c->get("unapproved_count"));
33 | }
34 |
35 | public function testCheckNewNotice(): void
36 | {
37 | Session::destroy(new Request());
38 | $this->resetSession();
39 | $this->resetCookie();
40 | $this->mergeAdminSession();
41 |
42 | $generator = new GenerateSampleComment();
43 | $generator->generateSampleComment('testblog2', 1, 1);
44 |
45 | $c = $this->reqGet("/admin/common/notice");
46 | $this->assertEquals(1, $c->get("unread_count"));
47 | $this->assertEquals(0, $c->get("unapproved_count"));
48 |
49 | $generator->generateSampleComment('testblog2', 1, 5);
50 | $c = $this->reqGet("/admin/common/notice");
51 | $this->assertEquals(6, $c->get("unread_count"));
52 | $this->assertEquals(0, $c->get("unapproved_count"));
53 | }
54 |
55 | // TODO 未承認コメントカウント、コメント設定周りの設定テストを書いてからか
56 | }
57 |
--------------------------------------------------------------------------------
/tests/App/Controller/Admin/Files/AjaxDeleteTest.php:
--------------------------------------------------------------------------------
1 | resetSession();
27 | $this->resetCookie();
28 | $this->mergeAdminSession();
29 |
30 | $ut = new UploadTest();
31 | $ut->uploadFile();
32 | $ut->uploadFile();
33 | $ut->uploadFile();
34 |
35 | $fm = new FilesModel();
36 | $before_files = $fm->find('all');
37 | // var_dump($before_files);
38 | $before_files_count = count($before_files);
39 |
40 | $delete_file_id_list = [];
41 | foreach ($before_files as $before_file) {
42 | $delete_file_id_list[] = $before_file['id'];
43 | }
44 | $will_be_delete_files_count = count($delete_file_id_list);
45 |
46 | $sig = $this->getSig();
47 |
48 | $c = $this->reqPost("/admin/files/ajax_delete", ['id' => $delete_file_id_list, 'sig' => $sig]);
49 |
50 | $this->assertEquals(0/*success*/, $c->get('json')['status']);
51 |
52 | // var_dump($c);
53 |
54 | $after_files = $fm->find('all');
55 | // var_dump($after_files);
56 | $this->assertCount($before_files_count - $will_be_delete_files_count, $after_files);
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/tests/App/Controller/Admin/Files/DeleteTest.php:
--------------------------------------------------------------------------------
1 | resetSession();
28 | $this->resetCookie();
29 | $this->mergeAdminSession();
30 |
31 | $ut = new UploadTest();
32 | $ut->uploadFile();
33 | $ut->uploadFile();
34 | $ut->uploadFile();
35 |
36 | // admin/files/uploadはガワの部分(アップロードフォームまで)
37 | $c = $this->reqGet("/admin/files/upload");
38 | $this->assertInstanceOf(FilesController::class, $c);
39 |
40 | $fm = new FilesModel();
41 | $before_files = $fm->find('all');
42 |
43 | $sig = $this->getSig();
44 |
45 | $delete_file_id = $before_files[0]['id'];
46 | $r = $this->reqGetBeRedirect("/admin/files/delete", ['id' => $delete_file_id, 'sig' => $sig]);
47 |
48 | $this->assertEquals('/admin/files/upload', $r->redirectUrl);
49 |
50 | $after_files = $fm->find('all');
51 |
52 | $this->assertCount(count($before_files) - 1, $after_files);
53 |
54 | $deleted_file = $fm->findByIdAndBlogId($delete_file_id, 'testblog2');
55 |
56 | $this->assertEmpty($deleted_file);
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/tests/App/Controller/User/EntriesController/IndexTest.php:
--------------------------------------------------------------------------------
1 | reqHttpsGet('/testblog1/?no=1');
16 | $this->assertStringStartsWith("getOutput());
17 | $this->assertStringContainsString("testblog1", $c->getOutput());
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/tests/App/Core/Html/UrlTest.php:
--------------------------------------------------------------------------------
1 | 'phpunit',
24 | 'HTTPS' => "on"
25 | ]
26 | );
27 | $url = Html::url($request, [
28 | 'controller' => 'user',
29 | 'action' => 'action',
30 | 'blog_id' => 'testblog1'
31 | ], false, false);
32 | $this->assertStringStartsWith('/', $url);
33 | $this->assertStringNotContainsString('http', $url);
34 | }
35 |
36 | public function testFullUrl()
37 | {
38 | $request = new Request(
39 | 'GET',
40 | '/',
41 | null,
42 | null,
43 | null,
44 | null,
45 | [
46 | 'HTTP_USER_AGENT' => 'phpunit',
47 | 'HTTPS' => "on"
48 | ]
49 | );
50 | $url = Html::url($request, [
51 | 'controller' => 'user',
52 | 'action' => 'action',
53 | 'blog_id' => 'testblog1'
54 | ], false, true);
55 | $this->assertStringStartsWith('https://', $url);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/tests/App/Core/Router/RouterTest.php:
--------------------------------------------------------------------------------
1 | assertEquals("Fc2blog\Web\Controller\User\BlogsController", $this->getClass("GET", "/"));
17 | $this->assertEquals("index", $this->getMethod("GET", "/"));
18 |
19 | $this->assertEquals("Fc2blog\Web\Controller\User\CommonController", $this->getClass("GET", "/admin/missing"));
20 | $this->assertEquals("error404", $this->getMethod("GET", "/admin/install"));
21 |
22 | $this->assertEquals("Fc2blog\Web\Controller\Admin\CommonController", $this->getClass("GET", "/admin/common/install"));
23 | $this->assertEquals("install", $this->getMethod("GET", "/admin/common/install"));
24 | }
25 |
26 | private function getClass($method, $path): string
27 | {
28 | $request = new Request($method, $path);
29 | return $request->className;
30 | }
31 |
32 | private function getMethod($method, $path): string
33 | {
34 | $request = new Request($method, $path);
35 | return $request->methodName;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/tests/App/Lib/CaptchaImage/.gitignore:
--------------------------------------------------------------------------------
1 | test_output.gif
--------------------------------------------------------------------------------
/tests/App/Model/BlogsModel/GetFullHostUrlByBlogIdTest.php:
--------------------------------------------------------------------------------
1 | assertEquals('https://localhost:8480', BlogsModel::getFullHostUrlByBlogId('testblog1', 'localhost'));
14 | $this->assertEquals('http://localhost:8080', BlogsModel::getFullHostUrlByBlogId('testblog2', 'localhost'));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/tests/App/Model/BlogsModel/GetSchemaByBlogIdTest.php:
--------------------------------------------------------------------------------
1 | assertEquals('https:', BlogsModel::getSchemaByBlogId('testblog1'));
14 | $this->assertEquals('http:', BlogsModel::getSchemaByBlogId('testblog2'));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/tests/App/Model/BlogsModel/GetSchemaBySslEnableValueTest.php:
--------------------------------------------------------------------------------
1 | assertEquals('https:', BlogsModel::getSchemaBySslEnableValue(BlogsModel::BLOG['SSL_ENABLE']['ENABLE']));
14 | $this->assertEquals('http:', BlogsModel::getSchemaBySslEnableValue(BlogsModel::BLOG['SSL_ENABLE']['DISABLE']));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/tests/App/Model/BlogsModel/IsValidBlogIdTest.php:
--------------------------------------------------------------------------------
1 | assertTrue(BlogsModel::isValidBlogId("testblog1"));
19 | $this->assertFalse(BlogsModel::isValidBlogId("containSymbol!"));
20 | $this->assertFalse(BlogsModel::isValidBlogId("aa"), "require more than 3 chars");
21 | $this->assertTrue(BlogsModel::isValidBlogId("aaa"), "require more than 3 chars");
22 | $this->assertTrue(BlogsModel::isValidBlogId(str_repeat("a", 50)), "require less 50 chars or less");
23 | $this->assertFalse(BlogsModel::isValidBlogId(str_repeat("a", 51)), "require less 50 chars or less");
24 | $this->assertFalse(BlogsModel::isValidBlogId("CAPITALCASENOTALLOWED"));
25 | $this->assertFalse(BlogsModel::isValidBlogId("no space allowed"));
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/tests/App/Model/PasswordResetTokenTest.php:
--------------------------------------------------------------------------------
1 | assertIsInt($last_insert_id);
23 |
24 | $token2 = PasswordResetTokenService::getByToken($token->token);
25 |
26 | // var_dump($token2);
27 |
28 | $this->assertInstanceOf(PasswordResetToken::class, $token2);
29 | }
30 |
31 | public function testDelete(): void
32 | {
33 | $user = UserService::getByLoginId('testadmin@localhost');
34 | $token = PasswordResetToken::factoryWithUser($user);
35 | $last_insert_id = PasswordResetTokenService::create($token);
36 | $this->assertIsInt($last_insert_id);
37 |
38 | $token2 = PasswordResetTokenService::getByToken($token->token);
39 |
40 | PasswordResetTokenService::revokeToken($token2);
41 |
42 | $token3 = PasswordResetTokenService::getByToken($token->token);
43 |
44 | $this->assertNull($token3);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/tests/App/Model/UserTest.php:
--------------------------------------------------------------------------------
1 | assertIsIterable($user);
21 |
22 | $this->assertEquals('testadmin@localhost', $user['login_id']);
23 |
24 | $this->assertEquals(7, count($user));
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/tests/App/Service/AccessBlockTest.php:
--------------------------------------------------------------------------------
1 | markTestSkipped();
16 | return;
17 | }
18 |
19 | $jp_ip_address = "133.0.0.1"; // Some JP address https://www.nic.ad.jp/ja/dns/jp-addr-block.html
20 | $r = new Request(null, null, null, null, null, null, [
21 | 'REMOTE_ADDR' => $jp_ip_address
22 | ]);
23 |
24 | $ab = new AccessBlock("JP");
25 | $this->assertTrue($ab->isUserBlockIp($r));
26 |
27 | $ab = new AccessBlock("JP,US");
28 | $this->assertTrue($ab->isUserBlockIp($r));
29 |
30 | $ab = new AccessBlock("US,JP");
31 | $this->assertTrue($ab->isUserBlockIp($r));
32 |
33 | $ab = new AccessBlock("US");
34 | $this->assertFalse($ab->isUserBlockIp($r));
35 |
36 | $ab = new AccessBlock();
37 | $this->assertFalse($ab->isUserBlockIp($r));
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/tests/App/Service/MailServiceTest.php:
--------------------------------------------------------------------------------
1 | setFrom("test_from@example.jp", "テスト送信主");
17 | $email->setTo("test_to@example.jp", "テスト送信先");
18 | $email->setSubjectAndBodyByTwig(
19 | TwigService::getTwigInstance(),
20 | 'mail/password_recovery_request.twig',
21 | ['url' => 'http://example.jp']
22 | );
23 | $this->assertStringContainsString('テスト送信主', print_r($email, true));
24 | $this->assertStringContainsString('テスト送信先', print_r($email, true));
25 | $this->assertStringContainsString('test_from@example.jp', print_r($email, true));
26 | $this->assertStringContainsString('test_to@example.jp', print_r($email, true));
27 | $this->assertStringContainsString('http://example.jp', print_r($email, true));
28 |
29 | MailService::send($email);
30 |
31 | $this->assertTrue(true); // 到達できればOK
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/tests/App/Service/UserServiceTest.php:
--------------------------------------------------------------------------------
1 | assertInstanceOf(User::class, $user);
18 |
19 | $old_pass_hash = $user->password;
20 |
21 | $user->setPassword('testadmin@localhost1');
22 | UserService::update($user);
23 |
24 | $user_new = UserService::getByLoginId($login_id);
25 | $this->assertNotEquals($old_pass_hash, $user_new->password);
26 |
27 | $this->assertTrue($user_new->verifyPassword('testadmin@localhost1'));
28 | $this->assertFalse($user_new->verifyPassword('testadmin@localhost'));
29 |
30 | UserService::updatePassword($user, 'testadmin@localhost');
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/tests/Helper/SampleDataGenerator/FakerTrait.php:
--------------------------------------------------------------------------------
1 | 0) {
27 | $request_data = [
28 | "id" => $faker->word . "blog",
29 | "name" => $faker->sentence(2) . "なブログ",
30 | "nickname" => $faker->name
31 | ];
32 |
33 | // 新規登録処理
34 | $errors_blog = $blogs_model->validate($request_data, $blog_data, array('id', 'name', 'nickname'));
35 | if (count($errors_blog) > 0) {
36 | throw new InvalidArgumentException("invalid request data:" . print_r($errors_blog, true));
37 | }
38 |
39 | $blog_data['user_id'] = $user_id;
40 |
41 | $id = $blogs_model->insert($blog_data);
42 |
43 | if ($id === false) {
44 | throw new RuntimeException("blog insert failed");
45 | }
46 |
47 | $generated_blog_list[] = $blogs_model->findById($id);
48 | }
49 |
50 | return $generated_blog_list;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/tests/Helper/SampleDataGenerator/GenerateSampleTemplate.php:
--------------------------------------------------------------------------------
1 | 0) {
24 | $device_list = App::DEVICES;
25 |
26 | $template_request = [
27 | "device_type" => $device_type ?? static::getRandomValue($device_list),
28 | "title" => $faker->sentence(3),
29 | "html" => $faker->randomHtml(),
30 | "css" => "/* this is pseudo css " . $faker->text() . "*/",
31 | ];
32 |
33 | // 新規登録処理
34 | $white_list = ['title', 'html', 'css', 'device_type'];
35 | $errors_blog_template = $blog_templates_model->validate($template_request, $blog_template_data, $white_list);
36 |
37 | if (count($errors_blog_template) > 0) {
38 | throw new InvalidArgumentException("invalid request:" . print_r($template_request, true));
39 | }
40 |
41 | $blog_template_data['blog_id'] = $blog_id;
42 |
43 | $id = $blog_templates_model->insert($blog_template_data);
44 |
45 | if ($id === false) {
46 | throw new RuntimeException("insert failed");
47 | }
48 |
49 | $template_list[] = $blog_templates_model->findById($id);
50 | }
51 |
52 | return $template_list;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/tests/TestTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(1, 1);
13 | }
14 | }
--------------------------------------------------------------------------------
/tests/bootstrap.php:
--------------------------------------------------------------------------------
1 | generateSampleBlog(1); // 1 is admin
19 |
20 |
--------------------------------------------------------------------------------
/tests/cli_generate_sample_category.php:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | generateSampleCategories('testblog2');
20 |
21 | //# リスト取得例
22 | //$list = $generator->getCategoryList('testblog2');
23 | //var_dump($list);
24 | //
25 | //# 全削除例
26 | //$generator->syncRemoveAllCategories('testblog2');
27 | //
28 | //# 全削除の確認
29 | //$list = $generator->getCategoryList('testblog2');
30 | //var_dump($list);
31 |
--------------------------------------------------------------------------------
/tests/cli_generate_sample_comment.php:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | generateSampleComment("testblog2", 1);
20 |
--------------------------------------------------------------------------------
/tests/cli_generate_sample_entries.php:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | generateSampleEntry('testblog2');
25 |
26 |
--------------------------------------------------------------------------------
/tests/cli_generate_sample_tag.php:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | generateSampleTagsToSpecifyEntry($blog_id, $entry_id);
22 | var_dump($tags);
23 |
--------------------------------------------------------------------------------
/tests/cli_generate_sample_template.php:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | generateSampleTemplate('testblog2');
20 |
--------------------------------------------------------------------------------
/tests/cli_generate_sample_upload_image.php:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | generateSampleUploadImage('testblog2');
20 |
--------------------------------------------------------------------------------
/tests/cli_load_fixture.php:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | findById($blog_id);
27 |
28 | if (empty($blog)) {
29 | echo "not found blog_id:{$blog_id}" . PHP_EOL;
30 | exit(1);
31 | }
32 |
33 | $blogs->resetToDefaultTemplateByBlogId($blog_id);
34 |
35 | echo "done" . PHP_EOL;
36 | exit(0);
37 |
--------------------------------------------------------------------------------
/tests/test_drop_all_table.sql:
--------------------------------------------------------------------------------
1 | -- need maintenance sometimes...
2 | DROP TABLE IF EXISTS `blog_plugins`;
3 | DROP TABLE IF EXISTS `blog_settings`;
4 | DROP TABLE IF EXISTS `blog_templates`;
5 | DROP TABLE IF EXISTS `blogs`;
6 | DROP TABLE IF EXISTS `categories`;
7 | DROP TABLE IF EXISTS `comments`;
8 | DROP TABLE IF EXISTS `entries`;
9 | DROP TABLE IF EXISTS `entry_categories`;
10 | DROP TABLE IF EXISTS `entry_tags`;
11 | DROP TABLE IF EXISTS `files`;
12 | DROP TABLE IF EXISTS `plugins`;
13 | DROP TABLE IF EXISTS `tags`;
14 | DROP TABLE IF EXISTS `users`;
--------------------------------------------------------------------------------
/tests/test_images/.gitignore:
--------------------------------------------------------------------------------
1 | *.png
2 | *.jpg
3 |
--------------------------------------------------------------------------------
/tests/test_images/download_samples.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | wget -O 0.png https://picsum.photos/200/300
3 | wget -O 1.png https://picsum.photos/200/300
4 | wget -O 2.png https://picsum.photos/200/300
5 | wget -O 3.png https://picsum.photos/200/300
6 | wget -O 4.png https://picsum.photos/200/300
7 | wget -O 5.png https://picsum.photos/200/300
8 | wget -O 6.png https://picsum.photos/200/300
9 | wget -O 7.png https://picsum.photos/200/300
10 | wget -O 8.png https://picsum.photos/200/300
11 | wget -O 9.png https://picsum.photos/200/300
12 |
--------------------------------------------------------------------------------