simpler version without much js, just vanilla pure simple php (with some libs)
This commit is contained in:
parent
e70f536b1a
commit
e7f3446506
47 changed files with 1915 additions and 363 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,2 +1,3 @@
|
|||
.idea
|
||||
*.patch
|
||||
node_modules
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"require": {
|
||||
"php-imap/php-imap": "~2.0"
|
||||
"php-imap/php-imap": "~2.0",
|
||||
"gnugat/PronounceableWord": "*"
|
||||
},
|
||||
"config": {
|
||||
"vendor-dir": "src/backend-libs"
|
||||
|
|
46
composer.lock
generated
46
composer.lock
generated
|
@ -4,9 +4,51 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "18ba77805fd530e1972050e6de7cd151",
|
||||
"content-hash": "357059f60b3f57be6e5f15b1df393a72",
|
||||
"hash": "781cc38d2f745ec4bfba29e440111b80",
|
||||
"content-hash": "70878ea12bce14861844baa8032688de",
|
||||
"packages": [
|
||||
{
|
||||
"name": "gnugat/PronounceableWord",
|
||||
"version": "2.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "git@github.com:gnugat/PronounceableWord.git",
|
||||
"reference": "60a19dc7148e92de35ea536b9f873b86365d48f0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/gnugat/PronounceableWord/zipball/60a19dc7148e92de35ea536b9f873b86365d48f0",
|
||||
"reference": "60a19dc7148e92de35ea536b9f873b86365d48f0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.2"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"PronounceableWord_": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Loïc Chardonnet"
|
||||
}
|
||||
],
|
||||
"description": "A light, customizable and simple library generating random and pronounceable words without using dictionaries or Markov chains.",
|
||||
"homepage": "https://github.com/gnugat/PronounceableWord",
|
||||
"keywords": [
|
||||
"generator",
|
||||
"pronounceable",
|
||||
"word"
|
||||
],
|
||||
"abandoned": true,
|
||||
"time": "2012-01-08 19:36:58"
|
||||
},
|
||||
{
|
||||
"name": "php-imap/php-imap",
|
||||
"version": "2.0.3",
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
|
||||
// autoload.php @generated by Composer
|
||||
|
||||
require_once __DIR__ . '/composer' . '/autoload_real.php';
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInit125dddd280a32cf75b181166154246ec::getLoader();
|
||||
|
|
|
@ -6,5 +6,6 @@ $vendorDir = dirname(dirname(__FILE__));
|
|||
$baseDir = dirname(dirname($vendorDir));
|
||||
|
||||
return array(
|
||||
'PronounceableWord_' => array($vendorDir . '/gnugat/PronounceableWord/src'),
|
||||
'PhpImap' => array($vendorDir . '/php-imap/php-imap/src'),
|
||||
);
|
||||
|
|
|
@ -9,6 +9,10 @@ class ComposerStaticInit125dddd280a32cf75b181166154246ec
|
|||
public static $prefixesPsr0 = array (
|
||||
'P' =>
|
||||
array (
|
||||
'PronounceableWord_' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/gnugat/PronounceableWord/src',
|
||||
),
|
||||
'PhpImap' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/php-imap/php-imap/src',
|
||||
|
|
|
@ -43,5 +43,49 @@
|
|||
"mail",
|
||||
"php"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "gnugat/PronounceableWord",
|
||||
"version": "2.0.0",
|
||||
"version_normalized": "2.0.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "git@github.com:gnugat/PronounceableWord.git",
|
||||
"reference": "60a19dc7148e92de35ea536b9f873b86365d48f0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/gnugat/PronounceableWord/zipball/60a19dc7148e92de35ea536b9f873b86365d48f0",
|
||||
"reference": "60a19dc7148e92de35ea536b9f873b86365d48f0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.2"
|
||||
},
|
||||
"time": "2012-01-08 19:36:58",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"PronounceableWord_": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Loïc Chardonnet"
|
||||
}
|
||||
],
|
||||
"description": "A light, customizable and simple library generating random and pronounceable words without using dictionaries or Markov chains.",
|
||||
"homepage": "https://github.com/gnugat/PronounceableWord",
|
||||
"keywords": [
|
||||
"generator",
|
||||
"pronounceable",
|
||||
"word"
|
||||
],
|
||||
"abandoned": true
|
||||
}
|
||||
]
|
||||
|
|
1
src/backend-libs/gnugat/PronounceableWord/.gitignore
vendored
Normal file
1
src/backend-libs/gnugat/PronounceableWord/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/nbproject
|
35
src/backend-libs/gnugat/PronounceableWord/CHANGELOG.rst
Normal file
35
src/backend-libs/gnugat/PronounceableWord/CHANGELOG.rst
Normal file
|
@ -0,0 +1,35 @@
|
|||
Change log
|
||||
==========
|
||||
|
||||
This file will provide the main changes between each new versions.
|
||||
|
||||
To get the diff for a specific change, go to https://github.com/gnugat/PronounceableWord/commit/XXX
|
||||
where XXX is the change hash.
|
||||
|
||||
To get the diff between two versions, go to https://github.com/gnugat/PronounceableWord/compare/X.Y.Z...A.B.C
|
||||
where X.Y.Z and A.B.C are the tag names.
|
||||
|
||||
2.0.0 (2012-01-08)
|
||||
------------------
|
||||
|
||||
* b9b3583: compatibility woth composer;
|
||||
* 01a495a: using lower probability for LinkedLetters configuration;
|
||||
* 8b27028: using a dependency injection container;
|
||||
* 24bd26c: using dependency injection pattern;
|
||||
* fe00216: complying to PSR-0 standard;
|
||||
* c6c7ea1: importing documentation from wiki.
|
||||
|
||||
1.0.2 (2012-01-03)
|
||||
------------------
|
||||
|
||||
* 1e34020: updating the version number.
|
||||
|
||||
1.0.1 (2012-01-03)
|
||||
------------------
|
||||
|
||||
* 3af0bff: copyright extended to 2012.
|
||||
|
||||
1.0.0 (2011-12-17)
|
||||
------------------
|
||||
|
||||
* a86dcea: Initial stable release.
|
27
src/backend-libs/gnugat/PronounceableWord/LICENSE.rst
Normal file
27
src/backend-libs/gnugat/PronounceableWord/LICENSE.rst
Normal file
|
@ -0,0 +1,27 @@
|
|||
LICENSE
|
||||
=======
|
||||
|
||||
License for the PronounceableWord PHP library
|
||||
|
||||
The MIT license
|
||||
---------------
|
||||
|
||||
Copyright (c) 2011-2012 Loic Chardonnet
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
107
src/backend-libs/gnugat/PronounceableWord/README.rst
Normal file
107
src/backend-libs/gnugat/PronounceableWord/README.rst
Normal file
|
@ -0,0 +1,107 @@
|
|||
PronounceableWord PHP library
|
||||
=============================
|
||||
|
||||
A light, customizable and simple PHP (>= 5.2) library, used to generate
|
||||
randomly pronounceable words, names and passwords without using database of
|
||||
existing words or big samples of text like with Markov chains.
|
||||
|
||||
**Warning**
|
||||
|
||||
Offensive or insulting words might be generated because of the random nature
|
||||
of the generator (see how to manage them in
|
||||
``./doc/manageOffensiveAndInsultingWords.rst``).
|
||||
|
||||
Installation and usage
|
||||
======================
|
||||
|
||||
First, get the last stable version, and put it in an accessible directory.
|
||||
|
||||
You can use composer to do so (http://packagist.org/), by adding in the
|
||||
``require`` of your file ``./composer.json`` the following entry:
|
||||
``"gnugat/PronounceableWord": "*"``.
|
||||
|
||||
You should have a fully operationnal pronounceable word generator::
|
||||
|
||||
<?php
|
||||
// File "/index.php".
|
||||
|
||||
require_once dirname(__FILE__) . '/vendor/PronounceableWord/src/PronounceableWord/DependencyInjectionContainer.php';
|
||||
|
||||
define('MINIMUM_LENGTH', 5);
|
||||
define('MAXIMUM_LENGTH', 11);
|
||||
|
||||
$length = rand(MINIMUM_LENGTH, MAXIMUM_LENGTH);
|
||||
|
||||
$container = new PronounceableWord_DependencyInjectionContainer();
|
||||
$generator = $container->getGenerator();
|
||||
$word = $generator->generateWordOfGivenLength($length);
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
To customize the algorithm, the letters used, the linked letters or the types,
|
||||
just copy and modify as you wish the files in the
|
||||
``./src/PronounceableWord/Configuration`` directory and then pass your
|
||||
configuration classes to the container (see how to configure in
|
||||
``./doc/configuration.rst``).
|
||||
|
||||
Tests
|
||||
-----
|
||||
|
||||
Tests are done using PHPUnit (https://github.com/sebastianbergmann/phpunit/)
|
||||
(>=3.5) in the ``./test`` directory (see how to test in ``./doc/tests.rst``).
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
Here is a sample of examples that can be generated (use the
|
||||
``./bin/generateExamples.php`` script for more):
|
||||
|
||||
======= ====== ======= ======== =========
|
||||
Length 5 6 7 8
|
||||
======= ====== ======= ======== =========
|
||||
1 vicas panori eropops absugrit
|
||||
2 ramsa verifu simbous nimpiowi
|
||||
3 kiclu impriar rubleru entumecu
|
||||
4 posup bivary kitocra vemolior
|
||||
5 utler rugisi kanomev pactabie
|
||||
======= ====== ======= ======== =========
|
||||
|
||||
Algorithm
|
||||
=========
|
||||
|
||||
Basically, the library will generate a word following these rules:
|
||||
|
||||
1. Choose randomly a letter;
|
||||
2. choose randomly a linked letter of different type;
|
||||
3. choose randomly a linked letter, of different type if the last letter is
|
||||
of consecutive types.
|
||||
|
||||
Where:
|
||||
|
||||
* "linked letter" is an arbitrary chosen letter that is expected to follow
|
||||
well the previous letter;
|
||||
* "types" would be voyels and consonants;
|
||||
* "consecutive" would be a group of two letters from the same "type".
|
||||
|
||||
The step 3 is repeated as many times as necessary.
|
||||
|
||||
Documentation
|
||||
=============
|
||||
|
||||
You can find more documentation at the following links:
|
||||
|
||||
* Copyright and MIT license: ``./LICENSE.rst``;
|
||||
* version and change log: ``./VERSION.rst`` and ``CHANGELOG.rst``;
|
||||
* technical and usage documentation: ``./doc/``.
|
||||
|
||||
Contributing
|
||||
============
|
||||
|
||||
1. Fork it: https://github.com/gnugat/PronounceableWord/fork_select ;
|
||||
2. create a branch (``git checkout -b my_branch``);
|
||||
3. commit your changes (``git commit -am "Changes description message"``);
|
||||
4. push to the branch (``git push origin my_branch``);
|
||||
5. create an Issue (https://github.com/gnugat/PronounceableWord/issues) with a
|
||||
link to your branch;
|
||||
6. wait for it to be accepted/argued.
|
10
src/backend-libs/gnugat/PronounceableWord/VERSION.rst
Normal file
10
src/backend-libs/gnugat/PronounceableWord/VERSION.rst
Normal file
|
@ -0,0 +1,10 @@
|
|||
VERSION
|
||||
=======
|
||||
|
||||
The purpose of this file is to point out the version of the PronounceableWord
|
||||
library.
|
||||
|
||||
Current version
|
||||
---------------
|
||||
|
||||
2.0.0
|
|
@ -0,0 +1,26 @@
|
|||
#!/usr/bin/env php
|
||||
|
||||
<?php
|
||||
/*
|
||||
* This file is part of the PronounceableWord library.
|
||||
*
|
||||
* (c) Loic Chardonnet
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE.txt
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
require_once dirname(__FILE__) . '/../src/PronounceableWord/DependencyInjectionContainer.php';
|
||||
|
||||
define('MINIMUM_LENGTH', 4);
|
||||
define('MAXIMUM_LENGTH', 9);
|
||||
|
||||
$container = new PronounceableWord_DependencyInjectionContainer();
|
||||
$generator = $container->getGenerator();
|
||||
|
||||
$maximumGenerationNumber = 20;
|
||||
for ($generationNumber = 0; $generationNumber < $maximumGenerationNumber; $generationNumber++) {
|
||||
$length = rand(MINIMUM_LENGTH, MAXIMUM_LENGTH);
|
||||
|
||||
echo $generator->generateWordOfGivenLength($length) . "\n";
|
||||
}
|
21
src/backend-libs/gnugat/PronounceableWord/composer.json
Normal file
21
src/backend-libs/gnugat/PronounceableWord/composer.json
Normal file
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"name": "gnugat/PronounceableWord",
|
||||
"type": "library",
|
||||
"description": "A light, customizable and simple library generating random and pronounceable words without using dictionaries or Markov chains.",
|
||||
"keywords": ["generator", "pronounceable", "word"],
|
||||
"homepage": "https://github.com/gnugat/PronounceableWord",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Loic Chardonnet"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.2"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"PronounceableWord_": "src/"
|
||||
}
|
||||
}
|
||||
}
|
210
src/backend-libs/gnugat/PronounceableWord/doc/configuration.rst
Normal file
210
src/backend-libs/gnugat/PronounceableWord/doc/configuration.rst
Normal file
|
@ -0,0 +1,210 @@
|
|||
Configuration
|
||||
=============
|
||||
|
||||
To generate pronounceable words, **PronouceableWord** uses three types of
|
||||
configuration:
|
||||
|
||||
================ ================================ ================================================
|
||||
Configuration What it defines What it allows
|
||||
================ ================================ ================================================
|
||||
Linked letters The link between letters To know which letters can follow a letter
|
||||
Letter types The types of the letters To alternate between consonants, vowels, etc...
|
||||
Generator The number of consecutive types To know when to alternate the types
|
||||
================ ================================ ================================================
|
||||
|
||||
PronouceableWord_Configuration_LinkedLetters
|
||||
--------------------------------------------
|
||||
|
||||
This class contains only one attribute (``lettersWithLinkedLetters``), which
|
||||
is an associative array:
|
||||
|
||||
Key
|
||||
A string of only one character representing the letter.
|
||||
|
||||
Value
|
||||
A string representing the letters supposed to follow well the **key**.
|
||||
|
||||
For example, having ``'b' => 'a'`` will allow to compose ``'ba'``.
|
||||
|
||||
PronouceableWord_Configuration_LetterTypes
|
||||
------------------------------------------
|
||||
|
||||
This class contains only one attribute (``letterTypesWithLetters``), which is
|
||||
an associative array:
|
||||
|
||||
Key
|
||||
The name of the type.
|
||||
|
||||
Value
|
||||
A string containing the letters of this type.
|
||||
|
||||
For example, defining the vowels would be: ``'vowels' => 'aeiouy'``.
|
||||
|
||||
PronounceableWord_Configuration_Generator
|
||||
-----------------------------------------
|
||||
|
||||
This class contains two attributes which must be integers superior to 1.:
|
||||
|
||||
===================================== ==============================================================================
|
||||
Attribute Example value and effect
|
||||
===================================== ==============================================================================
|
||||
maximumConsecutiveTypesAtTheBegining 1: if the first letter is a vowel, the second will be a consonant
|
||||
maximumConsecutiveTypesInTheWord 2: if the second and third letters are vowels, the fourth will be a consonant
|
||||
===================================== ==============================================================================
|
||||
|
||||
Default configuration
|
||||
=====================
|
||||
|
||||
The default configuration provides a set of linked letters based on the study
|
||||
of Data Compression (http://www.data-compression.com/english.shtml#second),
|
||||
using there statistical study of English text.
|
||||
|
||||
Some changes have been applied:
|
||||
|
||||
* only letters with a probability superior to 0.01 have been selected;
|
||||
* the letters 'j' and 'q' have been removed.
|
||||
|
||||
How to customize the configuration
|
||||
==================================
|
||||
|
||||
To customize the configuration, you need to:
|
||||
|
||||
1. copy the configuration classes in
|
||||
``./vendor/PronounceableWord/src/PronounceableWord/Configuration`` to your
|
||||
project configuration (e.g. ``./Configuration``);
|
||||
2. change the name of your configuration classes to avoid confusion, (e.g.
|
||||
replacing the prefix ``PronounceableWord`` by ``My``);
|
||||
3. change the content as you wish;
|
||||
4. set the configuration attributes in the dependency injection container
|
||||
with your own classes.
|
||||
|
||||
How to test the configuration
|
||||
=============================
|
||||
|
||||
To make sure your customized configuration is coherent and won't make
|
||||
**PronounceableWord** crash, you can test it as follow:
|
||||
|
||||
1. create a unit test extending the configuration test (from
|
||||
``./vendor/PronounceableWord/test/PronounceableWord/Tests/Configuration``);
|
||||
2. override the ``setUp`` method by initializing the ``configuration``
|
||||
attribute with your own configuration class.
|
||||
|
||||
To learn more about how to test, see ``./doc/tests.srt``.
|
||||
|
||||
Full Example
|
||||
============
|
||||
|
||||
Here is a complete example, to show how it works.
|
||||
|
||||
Customizing
|
||||
-----------
|
||||
|
||||
The configuration::
|
||||
|
||||
<?php
|
||||
// File copied: "./vendor/PronounceableWord/src/PronounceableWord/Configuration/LinkedLetters.php"
|
||||
// into: "./Configuration/LinkedLetters.php"
|
||||
|
||||
class My_Configuration_LinkedLetters {
|
||||
public $lettersWithLinkedLetters = array(
|
||||
'a' => 'bc',
|
||||
'b' => 'ac',
|
||||
'c' => 'a0',
|
||||
'0' => 'abc',
|
||||
);
|
||||
}
|
||||
|
||||
<?php
|
||||
// File copied: "./vendor/PronounceableWord/src/PronounceableWord/Configuration/LetterTypes.php"
|
||||
// into: "./Configuration/LetterTypes.php"
|
||||
|
||||
class My_Configuration_LetterTypes {
|
||||
public $letterTypesWithLetters = array(
|
||||
'vowels' => 'a',
|
||||
'consonants' => 'bc',
|
||||
'numbers' => '0',
|
||||
);
|
||||
}
|
||||
|
||||
<?php
|
||||
// File copied: "./vendor/PronounceableWord/src/PronounceableWord/Configuration/Generator.php"
|
||||
// into: "./Configuration/Generator.php"
|
||||
|
||||
class My_Configuration_Generator {
|
||||
public $maximumConsecutiveTypesAtTheBegining = 1;
|
||||
public $maximumConsecutiveTypesInTheWord = 2;
|
||||
}
|
||||
|
||||
This configuration is fine:
|
||||
|
||||
* each letters have at least one linked letters of a different type;
|
||||
* there are at least two different types;
|
||||
* every letters are present in the letter types;
|
||||
* the number of consecutive types are strictly positives.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
To use it, just set them into the container::
|
||||
|
||||
<?php
|
||||
// File "/index.php".
|
||||
|
||||
require_once dirname(__FILE__) . '/vendor/PronounceableWord/src/PronounceableWord/DependencyInjectionContainer.php';
|
||||
require_once dirname(__FILE__) . '/Configuration/LinkedLetters.php';
|
||||
require_once dirname(__FILE__) . '/Configuration/LetterTypes.php';
|
||||
require_once dirname(__FILE__) . '/Configuration/Generator.php';
|
||||
|
||||
define('MINIMUM_LENGTH', 5);
|
||||
define('MAXIMUM_LENGTH', 11);
|
||||
|
||||
$length = rand(MINIMUM_LENGTH, MAXIMUM_LENGTH);
|
||||
|
||||
$container = new PronounceableWord_DependencyInjectionContainer();
|
||||
$container->configurations['LinkedLetters'] = new My_Configuration_LinkedLetters();
|
||||
$container->configurations['LetterTypes'] = new My_Configuration_LetterTypes();
|
||||
$container->configurations['Generator'] = new My_Configuration_Generator();
|
||||
|
||||
$generator = $container->getGenerator();
|
||||
$word = $generator->generateWordOfGivenLength($length);
|
||||
|
||||
Testing
|
||||
-------
|
||||
|
||||
To test it, create the following unit tests::
|
||||
|
||||
<?php
|
||||
// File /test/Configuration/LinkedLettersTest.php
|
||||
|
||||
require_once dirname(__FILE__) . '/../../vendor/PronounceableWord/test/PronounceableWord/Tests/Configuration/LinkedLettersTest.php';
|
||||
require_once dirname(__FILE__) . '/../../Configuration/LinkedLetters.php';
|
||||
|
||||
class My_Tests_Configuration_LinkedLettersTest extends PronounceableWord_Tests_Configuration_LinkedLettersTest {
|
||||
public function setUp() {
|
||||
$this->configuration = new PronounceableWord_Configuration_LinkedLetters();
|
||||
}
|
||||
}
|
||||
|
||||
<?php
|
||||
// File /test/Configuration/LetterTypesTest.php
|
||||
|
||||
require_once dirname(__FILE__) . '/../../vendor/PronounceableWord/test/PronounceableWord/Tests/Configuration/LetterTypesTest.php';
|
||||
require_once dirname(__FILE__) . '/../../Configuration/LetterTypes.php';
|
||||
|
||||
class My_Tests_Configuration_LetterTypesTest extends PronounceableWord_Tests_Configuration_LetterTypesTest {
|
||||
public function setUp() {
|
||||
$this->configuration = new PronounceableWord_Configuration_LetterTypes();
|
||||
}
|
||||
}
|
||||
|
||||
<?php
|
||||
// File /test/Configuration/GeneratorTest.php
|
||||
|
||||
require_once dirname(__FILE__) . '/../../vendor/PronounceableWord/test/PronounceableWord/Tests/Configuration/GeneratorTest.php';
|
||||
require_once dirname(__FILE__) . '/../../Configuration/Generator.php';
|
||||
|
||||
class My_Tests_Configuration_GeneratorTest extends PronounceableWord_Tests_Configuration_GeneratorTest {
|
||||
public function setUp() {
|
||||
$this->configuration = new PronounceableWord_Configuration_Generator();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
Offensive and insulting words management
|
||||
========================================
|
||||
|
||||
Because PronounceableWord uses an algorithm using randomness,
|
||||
offensive or insulting words might be generated. The best way to manage them
|
||||
is to ceate a function that will filter them afterward.
|
||||
|
||||
These offensive words might be surrounded by other letters that would be fine
|
||||
otherwise, so you should replace it by a non-offensive one instead of just
|
||||
removing it.
|
||||
|
||||
To avoid generating unpronounceable words with this filter, try to be
|
||||
consistent with the configuration.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
Here is an example on how to manage them. With the default configuration, the
|
||||
word "insult" can be generated. Let's replace it by "insalt": the letter "s"
|
||||
has "a" as a linked letter, and the letter "a" has "l" has a linked letter::
|
||||
|
||||
<?php
|
||||
// File "/OffensiveAndInsultingWords.php".
|
||||
|
||||
class OffensiveAndInsultingWords {
|
||||
protected $offensiveAndInsultingWords = array(
|
||||
'insult' => 'insalt',
|
||||
);
|
||||
|
||||
public function filter($word) {
|
||||
foreach ($this->offensiveAndInsultingWords as $offensiveAndInsultingWord => $replacement) {
|
||||
$word = str_replace($offensiveAndInsultingWord, $replacement, $word);
|
||||
}
|
||||
|
||||
return $word;
|
||||
}
|
||||
}
|
||||
|
||||
Now, after generating your words with ``PronounceableWord_Generator``, you can
|
||||
use ``OffensiveAndInsultingWords`` to filter any words you might find offensive
|
||||
or insulting::
|
||||
|
||||
<?php
|
||||
// File "/index.php".
|
||||
|
||||
require_once dirname(__FILE__) . '/OffensiveAndInsultingWords.php';
|
||||
require_once dirname(__FILE__) . '/vendor/PronounceableWord/src/PronounceableWord/DependencyInjectionContainer.php';
|
||||
|
||||
define('MINIMUM_LENGTH', 5);
|
||||
define('MAXIMUM_LENGTH', 11);
|
||||
|
||||
$length = rand(MINIMUM_LENGTH, MAXIMUM_LENGTH);
|
||||
|
||||
$container = new PronounceableWord_DependencyInjectionContainer();
|
||||
$generator = $container->getGenerator();
|
||||
$offensiveAndInsultingWordManager = new OffensiveAndInsultingWords();
|
||||
|
||||
$word = $generator->generateWordOfGivenLength($length);
|
||||
$word = offensiveAndInsultingWordManager->filter($word);
|
|
@ -0,0 +1,175 @@
|
|||
The password generator example
|
||||
==============================
|
||||
|
||||
This page is intended to provide an example of usage and configuration, to
|
||||
generate passwords with PronounceableWord.
|
||||
|
||||
First create your project. You should have something like::
|
||||
|
||||
<?php
|
||||
// File "/index.php".
|
||||
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
First, get the last stable version, and put it in an accessible directory::
|
||||
|
||||
<?php
|
||||
// File "/index.php".
|
||||
|
||||
require_once dirname(__FILE__) . '/vendor/PronounceableWord/src/PronounceableWord/Generator.php';
|
||||
|
||||
For now, you should have a fully operationnal generator::
|
||||
|
||||
<?php
|
||||
// File "/index.php".
|
||||
|
||||
require_once dirname(__FILE__) . '/vendor/PronounceableWord/src/PronounceableWord/DependencyInjectionContainer.php';
|
||||
|
||||
define('MINIMUM_LENGTH', 5);
|
||||
define('MAXIMUM_LENGTH', 11);
|
||||
|
||||
$length = rand(MINIMUM_LENGTH, MAXIMUM_LENGTH);
|
||||
|
||||
$container = new PronounceableWord_DependencyInjectionContainer();
|
||||
$generator = $container->getGenerator();
|
||||
$password = $generator->generateWordOfGivenLength($length);
|
||||
|
||||
Configuration
|
||||
=============
|
||||
|
||||
Let's say that the standard configuration doesn't please you, because you think
|
||||
that password should also contain integers.
|
||||
|
||||
Linked letters configuration
|
||||
----------------------------
|
||||
|
||||
The first thing is to create your own linked letters configuration, with
|
||||
integers::
|
||||
|
||||
<?php
|
||||
// File "./Configuration/LinkedLetters.php"
|
||||
class My_Configuration_LinkedLetters {
|
||||
public $lettersWithLinkedLetters = array(
|
||||
'a' => 'bcdgiklmnprstvy0123456789',
|
||||
'b' => 'aeilorstuy0123456789',
|
||||
'c' => 'acehiklortu0123456789',
|
||||
'd' => 'aeiorsu0123456789',
|
||||
'e' => 'acdeilmnprstvxy0123456789',
|
||||
'f' => 'aefilortu0123456789',
|
||||
'g' => 'aeghilnorsu0123456789',
|
||||
'h' => 'aeiortu0123456789',
|
||||
'i' => 'acdefglmnorstv0123456789',
|
||||
'k' => 'aeilnos0123456789',
|
||||
'l' => 'adefilostuy0123456789',
|
||||
'm' => 'abeimoprsuy0123456789',
|
||||
'n' => 'acdegiosty0123456789',
|
||||
'o' => 'cdfklmnoprstuvw0123456789',
|
||||
'p' => 'aehiloprstu0123456789',
|
||||
'r' => 'acdegilmnorstuy0123456789',
|
||||
's' => 'acehilopstu0123456789',
|
||||
't' => 'aehilorstuy0123456789',
|
||||
'u' => 'abcdegilmnprst0123456789',
|
||||
'v' => 'aeino0123456789',
|
||||
'w' => 'aehinos0123456789',
|
||||
'x' => 'acehiptu0123456789',
|
||||
'y' => 'eiost0123456789',
|
||||
'z' => 'aeiloyz0123456789',
|
||||
'0' => 'abcdefghiklmnoprstuvwxyz0123456789',
|
||||
'1' => 'abcdefghiklmnoprstuvwxyz0123456789',
|
||||
'2' => 'abcdefghiklmnoprstuvwxyz0123456789',
|
||||
'3' => 'abcdefghiklmnoprstuvwxyz0123456789',
|
||||
'4' => 'abcdefghiklmnoprstuvwxyz0123456789',
|
||||
'5' => 'abcdefghiklmnoprstuvwxyz0123456789',
|
||||
'6' => 'abcdefghiklmnoprstuvwxyz0123456789',
|
||||
'7' => 'abcdefghiklmnoprstuvwxyz0123456789',
|
||||
'8' => 'abcdefghiklmnoprstuvwxyz0123456789',
|
||||
'9' => 'abcdefghiklmnoprstuvwxyz0123456789',
|
||||
);
|
||||
}
|
||||
|
||||
Letter type configuration
|
||||
-------------------------
|
||||
|
||||
Then create the letter types configuration with integers::
|
||||
|
||||
<?php
|
||||
// File "./Configuration/LetterTypes.php"
|
||||
class My_Configuration_LetterTypes {
|
||||
public $letterTypesWithLetters = array(
|
||||
'voyels' => 'aeiouy',
|
||||
'consonants' => 'bcdfghklmnprstvwxz',
|
||||
'integers' => '0123456789',
|
||||
);
|
||||
}
|
||||
|
||||
Adding your configuration
|
||||
-------------------------
|
||||
|
||||
Finally, simply add your configuration into the container::
|
||||
|
||||
<?php
|
||||
// File "/index.php".
|
||||
|
||||
require_once dirname(__FILE__) . '/vendor/PronounceableWord/src/PronounceableWord/DependencyInjectionContainer.php';
|
||||
require_once dirname(__FILE__) . './Configuration/LinkedLetters.php';
|
||||
require_once dirname(__FILE__) . './Configuration/LetterTypes.php';
|
||||
|
||||
define('MINIMUM_LENGTH', 5);
|
||||
define('MAXIMUM_LENGTH', 11);
|
||||
|
||||
$length = rand(MINIMUM_LENGTH, MAXIMUM_LENGTH);
|
||||
|
||||
$container = new PronounceableWord_DependencyInjectionContainer();
|
||||
$container->configurations['LinkedLetters'] = new My_Configuration_LinkedLetters();
|
||||
$container->configurations['LetterTypes'] = new My_Configuration_LetterTypes();
|
||||
|
||||
$generator = $container->getGenerator();
|
||||
$password = $generator->generateWordOfGivenLength($length);
|
||||
|
||||
Conclusion
|
||||
==========
|
||||
|
||||
You now have a pronounceable password generator. If you want to use upper and
|
||||
lower case, you should use a function aferwards::
|
||||
|
||||
<?php
|
||||
// File "./addUppercase.php"
|
||||
define('CHOOSE_LOWER_CASE', 0);
|
||||
define('CHOOSE_UPPER_CASE', 1);
|
||||
|
||||
function addUppercase($word) {
|
||||
$maximumLetterIndex = strlen($word);
|
||||
for ($letterIndex = 0; $letterIndex < $maximumLetterIndex, $letterIndex++) {
|
||||
$choice = rand(CHOOSE_LOWER_CASE, CHOOSE_UPPER_CASE);
|
||||
if (CHOOSE_UPPER_CASE === $choice) {
|
||||
$word[$letterIndex] = strtoupper($word[$letterIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
return $word;
|
||||
}
|
||||
|
||||
And::
|
||||
|
||||
<?php
|
||||
// File "/index.php".
|
||||
|
||||
require_once dirname(__FILE__) . '/vendor/PronounceableWord/src/PronounceableWord/DependencyInjectionContainer.php';
|
||||
require_once dirname(__FILE__) . './Configuration/LinkedLetters.php';
|
||||
require_once dirname(__FILE__) . './Configuration/LetterTypes.php';
|
||||
|
||||
define('MINIMUM_LENGTH', 5);
|
||||
define('MAXIMUM_LENGTH', 11);
|
||||
|
||||
$length = rand(MINIMUM_LENGTH, MAXIMUM_LENGTH);
|
||||
|
||||
$container = new PronounceableWord_DependencyInjectionContainer();
|
||||
$container->configurations['LinkedLetters'] = new My_Configuration_LinkedLetters();
|
||||
$container->configurations['LetterTypes'] = new My_Configuration_LetterTypes();
|
||||
|
||||
$generator = $container->getGenerator();
|
||||
$password = $generator->generateWordOfGivenLength($length);
|
||||
|
||||
$password = addUppercase($password);
|
31
src/backend-libs/gnugat/PronounceableWord/doc/roadmap.rst
Normal file
31
src/backend-libs/gnugat/PronounceableWord/doc/roadmap.rst
Normal file
|
@ -0,0 +1,31 @@
|
|||
Roadmap
|
||||
=======
|
||||
|
||||
This file will establish the fetaures plan for the next versions.
|
||||
|
||||
2.1.0
|
||||
-----
|
||||
|
||||
The following features must be implemented to reach the version 2.1.0:
|
||||
|
||||
* Choice of first letter based on the letters following 'SPACE' in the
|
||||
Data Compression study: http://www.data-compression.com/english.shtml#second;
|
||||
* choice of last letter based on the letters coming before 'SPACE' in the
|
||||
Data Compression study: http://www.data-compression.com/english.shtml#second.
|
||||
|
||||
2.0.0
|
||||
-----
|
||||
|
||||
In order to reach the version 2.0.0, the following features must be
|
||||
implemented:
|
||||
|
||||
* moving the documentation from the Github wiki to the git repository;
|
||||
* conforming to the standard PSR-0:
|
||||
https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md;
|
||||
* using the Dependency Injection design pattern to load configuration:
|
||||
http://en.wikipedia.org/wiki/Dependency_injection;
|
||||
* using Dependency Injection Container;
|
||||
* using, as the linked letters default configuration, letters from the Data
|
||||
Compression study superior to 0.01 instead of 0.001:
|
||||
http://www.data-compression.com/english.shtml#second;
|
||||
* being compatible with composer.
|
40
src/backend-libs/gnugat/PronounceableWord/doc/tests.rst
Normal file
40
src/backend-libs/gnugat/PronounceableWord/doc/tests.rst
Normal file
|
@ -0,0 +1,40 @@
|
|||
Tests
|
||||
=====
|
||||
|
||||
In order to keep PronounceableWordGenerator stable and to maintain a high
|
||||
quality, tests have been written using PHPUnit >= 3.5
|
||||
(https://github.com/sebastianbergmann/phpunit/).
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
Before doing any test, you must do some installations.
|
||||
|
||||
Installing PEAR
|
||||
---------------
|
||||
|
||||
PEAR (http://pear.php.net/) is necessary to use PHPUnit. To install it, follow
|
||||
these instructions: http://pear.php.net/manual/en/installation.getting.php
|
||||
|
||||
If you are on Windows, and using WAMP or EasyPHP (or maybe others web
|
||||
development plateforms), you might encounter the following error::
|
||||
|
||||
phar "C:\wamp\bin\php\php5.3.0\PEAR\go-pear.phar" does not have a signature PHP Warning: require_once(phar://go-pear.par/index.php): failed to open stream: phar error: invalid url or non-existent phar "phar://go-pear.phar/index.php" in C:\wamp\bin\php\php5.3.0\PEAR\go-pear.phar on line 1236
|
||||
|
||||
Warning: require_once(phar://go-pear.par/index.php): failed to open stream: phar error: invalid url or non-existent phar "phar://go-pear.phar/index.php" in C:\wamp\bin\php\php5.3.0\PEAR\go-pear.phar on line 1236 Press any key to continue...
|
||||
|
||||
This is because the PHP setting "phar.require_hash" is set to "On" by default.
|
||||
If you set it to "Off" in your "php.ini", you should be able to continue.
|
||||
|
||||
Installing PHPUnit
|
||||
------------------
|
||||
|
||||
Once PEAR is installed, you can use it to install PHPUnit by following these
|
||||
instructions: http://www.phpunit.de/manual/3.0/en/installation.html
|
||||
|
||||
Running the tests
|
||||
=================
|
||||
|
||||
Tests can be run by CLI, using the following command::
|
||||
|
||||
phpunit ./test
|
|
@ -0,0 +1,54 @@
|
|||
Versionning
|
||||
===========
|
||||
|
||||
This file will document the versionning process of the PHP library
|
||||
PronounceableWord.
|
||||
|
||||
Version number
|
||||
==============
|
||||
|
||||
The version number will follow the X.Y.Z format. The following table describes
|
||||
the meaning of incrementation for each number:
|
||||
|
||||
======== =============================================================================================
|
||||
Version Description
|
||||
======== =============================================================================================
|
||||
#.0.0 Modification impacting on the public usage
|
||||
0.#.0 Modification not impacting on the public usage
|
||||
0.0.# Small modification not impacting on the public usage, like bug fixes and adding of new tests
|
||||
======== =============================================================================================
|
||||
|
||||
Branching model
|
||||
===============
|
||||
|
||||
The PronounceableWord project uses Git to its full potential, following
|
||||
the advice of this article:
|
||||
http://nvie.com/posts/a-successful-git-branching-model/ .
|
||||
|
||||
================== =============== ================================= ====================================
|
||||
Repository/Branch Pull from Merge to Description
|
||||
================== =============== ================================= ====================================
|
||||
origin/master Stable branch, actual release.
|
||||
origin/develop origin/master origin/master Stable branch, for next release.
|
||||
x/hotfix-* origin/master origin/master and origin/develop Bug fixes branch for origin/master.
|
||||
x/x origin/develop origin/develop Feature branch.
|
||||
================== =============== ================================= ====================================
|
||||
|
||||
Tags
|
||||
----
|
||||
|
||||
Tags are created from the origin/master branch, incrementing the version number.
|
||||
|
||||
x/hotfix-* branches
|
||||
-------------------
|
||||
|
||||
The repository is named x because it can be from another repository (through
|
||||
forks), and the branch is called hotfix-* because it is suffixed by "hotfix-"
|
||||
and named after the feature it will fix.
|
||||
|
||||
x/x branches
|
||||
------------
|
||||
|
||||
The repository is named x because it can be from another repository (through
|
||||
forks), and the branch is called x because it is named after the feature it
|
||||
will implement.
|
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
class PronounceableWord_Configuration_Generator {
|
||||
public $maximumConsecutiveTypesAtTheBegining = 1;
|
||||
public $maximumConsecutiveTypesInTheWord = 2;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
class PronounceableWord_Configuration_LetterTypes {
|
||||
public $letterTypesWithLetters = array(
|
||||
'voyels' => 'aeiouy',
|
||||
'consonants' => 'bcdfghklmnprstvwxz',
|
||||
);
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
class PronounceableWord_Configuration_LinkedLetters {
|
||||
public $lettersWithLinkedLetters = array(
|
||||
'a' => 'bcdgiklmnprstvy',
|
||||
'b' => 'aeilorstuy',
|
||||
'c' => 'acehiklortu',
|
||||
'd' => 'aeiorsu',
|
||||
'e' => 'acdeilmnprstvxy',
|
||||
'f' => 'aefilortu',
|
||||
'g' => 'aeghilnorsu',
|
||||
'h' => 'aeiortu',
|
||||
'i' => 'acdefglmnorstv',
|
||||
'k' => 'aeilnos',
|
||||
'l' => 'adefilostuy',
|
||||
'm' => 'abeimoprsuy',
|
||||
'n' => 'acdegiosty',
|
||||
'o' => 'cdfklmnoprstuvw',
|
||||
'p' => 'aehiloprstu',
|
||||
'r' => 'acdegilmnorstuy',
|
||||
's' => 'acehilopstu',
|
||||
't' => 'aehilorstuy',
|
||||
'u' => 'abcdegilmnprst',
|
||||
'v' => 'aeino',
|
||||
'w' => 'aehinos',
|
||||
'x' => 'acehiptu',
|
||||
'y' => 'eiost',
|
||||
'z' => 'aeiloyz',
|
||||
);
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of the PronounceableWord library.
|
||||
*
|
||||
* (c) Loic Chardonnet
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE.txt
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
require_once dirname(__FILE__) . '/Configuration/LinkedLetters.php';
|
||||
require_once dirname(__FILE__) . '/Configuration/LetterTypes.php';
|
||||
require_once dirname(__FILE__) . '/Configuration/Generator.php';
|
||||
require_once dirname(__FILE__) . '/LinkedLetters.php';
|
||||
require_once dirname(__FILE__) . '/LetterTypes.php';
|
||||
require_once dirname(__FILE__) . '/LastLettersConsecutiveTypes.php';
|
||||
require_once dirname(__FILE__) . '/Generator.php';
|
||||
|
||||
class PronounceableWord_DependencyInjectionContainer {
|
||||
public $configurations = array();
|
||||
public $classNames = array();
|
||||
|
||||
public function __construct() {
|
||||
$this->configurations['Generator'] = new PronounceableWord_Configuration_Generator();
|
||||
$this->configurations['LinkedLetters'] = new PronounceableWord_Configuration_LinkedLetters();
|
||||
$this->configurations['LetterTypes'] = new PronounceableWord_Configuration_LetterTypes();
|
||||
|
||||
$this->classNames['LinkedLetters'] = 'PronounceableWord_LinkedLetters';
|
||||
$this->classNames['LetterTypes'] = 'PronounceableWord_LetterTypes';
|
||||
$this->classNames['LastLettersConsecutiveTypes'] = 'PronounceableWord_LastLettersConsecutiveTypes';
|
||||
$this->classNames['Generator'] = 'PronounceableWord_Generator';
|
||||
}
|
||||
|
||||
public function getGenerator() {
|
||||
$generatorClass = $this->classNames['Generator'];
|
||||
$generatorInstance = new $generatorClass(
|
||||
$this->getLinkedLetters(),
|
||||
$this->getLetterTypes(),
|
||||
$this->getLastLettersConsecutiveTypes(),
|
||||
$this->configurations['Generator']
|
||||
);
|
||||
|
||||
return $generatorInstance;
|
||||
}
|
||||
|
||||
public function getLinkedLetters() {
|
||||
$linkedLettersClass = $this->classNames['LinkedLetters'];
|
||||
$linkedLettersInstance = new $linkedLettersClass($this->configurations['LinkedLetters']);
|
||||
|
||||
return $linkedLettersInstance;
|
||||
}
|
||||
|
||||
public function getLetterTypes() {
|
||||
$lettersTypesClass = $this->classNames['LetterTypes'];
|
||||
$lettersTypesInstance = new $lettersTypesClass($this->configurations['LetterTypes']);
|
||||
|
||||
return $lettersTypesInstance;
|
||||
}
|
||||
|
||||
public function getLastLettersConsecutiveTypes() {
|
||||
$lastLettersConsecutiveTypesClass = $this->classNames['LastLettersConsecutiveTypes'];
|
||||
$lastLettersConsecutiveTypesInstance = new $lastLettersConsecutiveTypesClass($this->getLetterTypes());
|
||||
|
||||
return $lastLettersConsecutiveTypesInstance;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of the PronounceableWord library.
|
||||
*
|
||||
* (c) Loic Chardonnet
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE.txt
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
class PronounceableWord_Generator {
|
||||
protected $word;
|
||||
protected $length;
|
||||
|
||||
protected $linkedLetters;
|
||||
protected $letterTypes;
|
||||
protected $lastLettersConsecutiveTypes;
|
||||
protected $configuration;
|
||||
|
||||
public function __construct($linkedLetter, $letterTypes, $lastLettersConsecutiveTypes, $configuration) {
|
||||
$this->linkedLetters = $linkedLetter;
|
||||
$this->letterTypes = $letterTypes;
|
||||
$this->lastLettersConsecutiveTypes = $lastLettersConsecutiveTypes;
|
||||
$this->configuration = $configuration;
|
||||
}
|
||||
|
||||
public function generateWordOfGivenLength($givenLength) {
|
||||
$this->word = '';
|
||||
$this->length = 0;
|
||||
for ($letterNumber = 0; $letterNumber < $givenLength; $letterNumber++) {
|
||||
$this->word .= $this->pickNextLetter();
|
||||
$this->length = strlen($this->word);
|
||||
}
|
||||
|
||||
return $this->word;
|
||||
}
|
||||
|
||||
protected function pickNextLetter() {
|
||||
$pickedLetter = '';
|
||||
|
||||
if (0 === $this->length) {
|
||||
$pickedLetter = $this->pickFirstLetter();
|
||||
} elseif ($this->length <= $this->configuration->maximumConsecutiveTypesAtTheBegining) {
|
||||
$pickedLetter = $this->pickLinkedLetterOfDifferentType($this->word[0]);
|
||||
} else {
|
||||
$pickedLetter = $this->pickLinkedLetterOfDifferentTypeIfLastLettersAreOfConsecutiveTypes();
|
||||
}
|
||||
|
||||
return $pickedLetter;
|
||||
}
|
||||
|
||||
protected function pickFirstLetter() {
|
||||
return $this->linkedLetters->pickLetter();
|
||||
}
|
||||
|
||||
protected function pickLinkedLetterOfDifferentType($letter) {
|
||||
$letterType = $this->letterTypes->getLetterType($letter);
|
||||
$lettersToAvoid = $this->letterTypes->getLettersOfGivenType($letterType);
|
||||
|
||||
return $this->linkedLetters->pickLinkedLetterDifferentFromGivenLetters($letter, $lettersToAvoid);
|
||||
}
|
||||
|
||||
protected function pickLinkedLetterOfDifferentTypeIfLastLettersAreOfConsecutiveTypes() {
|
||||
$lastLetter = $this->word[$this->length - 1];
|
||||
$consecutiveTypes = $this->lastLettersConsecutiveTypes->countFromWord($this->word);
|
||||
|
||||
$pickedLetter = '';
|
||||
if ($consecutiveTypes === $this->configuration->maximumConsecutiveTypesInTheWord) {
|
||||
$pickedLetter = $this->pickLinkedLetterOfDifferentType($lastLetter);
|
||||
} else {
|
||||
$pickedLetter = $this->linkedLetters->pickLinkedLetter($lastLetter);
|
||||
}
|
||||
|
||||
return $pickedLetter;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of the PronounceableWord library.
|
||||
*
|
||||
* (c) Loic Chardonnet
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE.txt
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
class PronounceableWord_LastLettersConsecutiveTypes {
|
||||
protected $letterTypes;
|
||||
|
||||
public function __construct($letterTypes) {
|
||||
$this->letterTypes = $letterTypes;
|
||||
}
|
||||
|
||||
public function countFromWord($word) {
|
||||
$letterIndex = strlen($word) - 1;
|
||||
$letter = $word[$letterIndex];
|
||||
$type = $this->letterTypes->getLetterType($letter);
|
||||
$consecutiveTypesCount = 1;
|
||||
|
||||
for ($letterIndex = $letterIndex - 1; $letterIndex >= 0; $letterIndex--) {
|
||||
$letter = $word[$letterIndex];
|
||||
if ($this->letterTypes->getLetterType($letter) !== $type) {
|
||||
break;
|
||||
}
|
||||
$consecutiveTypesCount++;
|
||||
}
|
||||
|
||||
return $consecutiveTypesCount;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of the PronounceableWord library.
|
||||
*
|
||||
* (c) Loic Chardonnet
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE.txt
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
class PronounceableWord_LetterTypes {
|
||||
protected $configuration;
|
||||
|
||||
public function __construct($configuration) {
|
||||
$this->configuration = $configuration;
|
||||
}
|
||||
|
||||
public function getLetterType($letter) {
|
||||
$type = '';
|
||||
foreach ($this->configuration->letterTypesWithLetters as $letterType => $letters) {
|
||||
if (false !== strpos($letters, $letter)) {
|
||||
$type = $letterType;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $type;
|
||||
}
|
||||
|
||||
public function getLettersOfGivenType($type) {
|
||||
return $this->configuration->letterTypesWithLetters[$type];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of the PronounceableWord library.
|
||||
*
|
||||
* (c) Loic Chardonnet
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE.txt
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
class PronounceableWord_LinkedLetters {
|
||||
protected $configuration;
|
||||
|
||||
public function __construct($configuration) {
|
||||
$this->configuration = $configuration;
|
||||
}
|
||||
public function pickLetter() {
|
||||
$pickedLetter = array_rand($this->configuration->lettersWithLinkedLetters);
|
||||
|
||||
return $pickedLetter;
|
||||
}
|
||||
|
||||
public function pickLinkedLetter($letter) {
|
||||
$linkedLetters = $this->configuration->lettersWithLinkedLetters[$letter];
|
||||
|
||||
return $this->pickLetterFromGivenLetters($linkedLetters);
|
||||
}
|
||||
|
||||
protected function pickLetterFromGivenLetters($letters) {
|
||||
$minLetterIndex = 0;
|
||||
$maxLetterIndex = strlen($letters) - 1;
|
||||
$pickedLetterIndex = rand($minLetterIndex, $maxLetterIndex);
|
||||
|
||||
$pickedLetter = $letters[$pickedLetterIndex];
|
||||
|
||||
return $pickedLetter;
|
||||
}
|
||||
|
||||
public function pickLinkedLetterDifferentFromGivenLetters($letter, $letters) {
|
||||
$linkedLetters = $this->configuration->lettersWithLinkedLetters[$letter];
|
||||
|
||||
$letterChoices = $this->removeGivenLettersFromGivenLinkedLetters($letters, $linkedLetters);
|
||||
|
||||
return $this->pickLetterFromGivenLetters($letterChoices);
|
||||
}
|
||||
|
||||
protected function removeGivenLettersFromGivenLinkedLetters($letters, $linkedLetters) {
|
||||
$maximumLetterIndex = strlen($letters);
|
||||
for ($letterIndex = 0; $letterIndex < $maximumLetterIndex; $letterIndex++) {
|
||||
$linkedLetters = str_replace($letters[$letterIndex], '', $linkedLetters);
|
||||
}
|
||||
|
||||
return $linkedLetters;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of the PronounceableWord library.
|
||||
*
|
||||
* (c) Loic Chardonnet
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE.txt
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
require_once dirname(__FILE__) . '/../../../../src/PronounceableWord/Configuration/Generator.php';
|
||||
|
||||
class PronounceableWord_Tests_Configuration_GeneratorTest extends PHPUnit_Framework_TestCase {
|
||||
protected $minimumPositiveNumber = 1;
|
||||
|
||||
public function setUp() {
|
||||
$this->configuration = new PronounceableWord_Configuration_Generator();
|
||||
}
|
||||
|
||||
public function testIsMaximumConsecutiveTypesAtTheBeginingPositive() {
|
||||
$this->assertGreaterThanOrEqual($this->minimumPositiveNumber, $this->configuration->maximumConsecutiveTypesAtTheBegining);
|
||||
}
|
||||
|
||||
public function testIsMaximumConsecutiveTypesInTheWordPositive() {
|
||||
$this->assertGreaterThanOrEqual($this->minimumPositiveNumber, $this->configuration->maximumConsecutiveTypesInTheWord);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of the PronounceableWord library.
|
||||
*
|
||||
* (c) Loic Chardonnet
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE.txt
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
require_once dirname(__FILE__) . '/../../../../src/PronounceableWord/Configuration/LetterTypes.php';
|
||||
|
||||
class PronounceableWord_Tests_Configuration_LetterTypesTest extends PHPUnit_Framework_TestCase {
|
||||
public function setUp() {
|
||||
$this->configuration = new PronounceableWord_Configuration_LetterTypes();
|
||||
}
|
||||
public function testAreLettersInOnlyOneType() {
|
||||
foreach ($this->configuration->letterTypesWithLetters as $currentType => $lettersOfCurrentType) {
|
||||
$maximumLetterIndex = strlen($lettersOfCurrentType);
|
||||
$areLettersInOnlyOneType = true;
|
||||
foreach ($this->configuration->letterTypesWithLetters as $checkedType => $lettersOfCheckedType) {
|
||||
if ($currentType !== $checkedType) {
|
||||
for ($letterIndex = 0; $letterIndex < $maximumLetterIndex; $letterIndex++) {
|
||||
$isLetterInLetters = strpos($lettersOfCheckedType, $lettersOfCurrentType[$letterIndex]);
|
||||
|
||||
if (false !== $isLetterInLetters) {
|
||||
$areLettersInOnlyOneType = false;
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->assertTrue($areLettersInOnlyOneType);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of the PronounceableWord library.
|
||||
*
|
||||
* (c) Loic Chardonnet
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE.txt
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
require_once dirname(__FILE__) . '/../../../../src/PronounceableWord/Configuration/LinkedLetters.php';
|
||||
require_once dirname(__FILE__) . '/../../../../src/PronounceableWord/Configuration/LetterTypes.php';
|
||||
require_once dirname(__FILE__) . '/../../../../src/PronounceableWord/LetterTypes.php';
|
||||
|
||||
class PronounceableWord_Tests_Configuration_LinkedLettersAndTypesTest extends PHPUnit_Framework_TestCase {
|
||||
public function setUp() {
|
||||
$this->letterTypesConfiguration = new PronounceableWord_Configuration_LetterTypes();
|
||||
$this->linkedLettersConfiguration = new PronounceableWord_Configuration_LinkedLetters();
|
||||
}
|
||||
|
||||
public function testAreAllLettersFromLinkedLettersInLettersFromLetterTypes() {
|
||||
foreach ($this->linkedLettersConfiguration->lettersWithLinkedLetters as $letter => $linkedLettersToIgnore) {
|
||||
$isLetterInTypes = false;
|
||||
foreach ($this->letterTypesConfiguration->letterTypesWithLetters as $lettersOfType) {
|
||||
$isLetterInLetters = strpos($lettersOfType, $letter);
|
||||
|
||||
if (false !== $isLetterInLetters) {
|
||||
$isLetterInTypes = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$this->assertTrue($isLetterInTypes);
|
||||
}
|
||||
}
|
||||
|
||||
public function testHaveLettersAtLeastOneLinkedLetterOfDifferentType() {
|
||||
$letterTypes = new PronounceableWord_LetterTypes($this->letterTypesConfiguration);
|
||||
$linkedLettersConfiguration = new PronounceableWord_Configuration_LinkedLetters();
|
||||
|
||||
foreach ($this->linkedLettersConfiguration->lettersWithLinkedLetters as $letter => $linkedLetters) {
|
||||
$letterType = $letterTypes->getLetterType($letter);
|
||||
|
||||
$hasOneDifferentType = false;
|
||||
$maximumLetterIndex = strlen($linkedLetters);
|
||||
for ($letterIndex = 0; $letterIndex < $maximumLetterIndex; $letterIndex++) {
|
||||
$linkedLetterType = $letterTypes->getLetterType($linkedLetters[$letterIndex]);
|
||||
|
||||
if ($letterType !== $linkedLetterType) {
|
||||
$hasOneDifferentType = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$this->assertTrue($hasOneDifferentType);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of the PronounceableWord library.
|
||||
*
|
||||
* (c) Loic Chardonnet
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE.txt
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
require_once dirname(__FILE__) . '/../../../../src/PronounceableWord/Configuration/LinkedLetters.php';
|
||||
|
||||
class PronounceableWord_Tests_Configuration_LinkedLettersTest extends PHPUnit_Framework_TestCase {
|
||||
public function setUp() {
|
||||
$this->configuration = new PronounceableWord_Configuration_LinkedLetters();
|
||||
}
|
||||
|
||||
public function testAreAllLettersInAtLeastOneLinkedLetters() {
|
||||
foreach ($this->configuration->lettersWithLinkedLetters as $letter => $linkedLettersToIgnore) {
|
||||
$isInAtLeastOneLinkedLetters = false;
|
||||
foreach ($this->configuration->lettersWithLinkedLetters as $letterToIgnore => $linkedLetters) {
|
||||
$isLetterInLinkedLetters = strpos($linkedLetters, $letter);
|
||||
|
||||
if (false !== $isLetterInLinkedLetters) {
|
||||
$isInAtLeastOneLinkedLetters = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$this->assertTrue($isInAtLeastOneLinkedLetters);
|
||||
}
|
||||
}
|
||||
|
||||
public function testAreAllLinkedLettersInLetters() {
|
||||
foreach ($this->configuration->lettersWithLinkedLetters as $letterToIgnore => $linkedLetters) {
|
||||
$isLinkedLetterInLetters = false;
|
||||
foreach ($this->configuration->lettersWithLinkedLetters as $letter => $linkedLettersToIgnore) {
|
||||
$isLetterInLinkedLetters = strpos($linkedLetters, $letter);
|
||||
|
||||
if (false !== $isLetterInLinkedLetters) {
|
||||
$isInAtLeastOneLinkedLetters = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$this->assertTrue($isInAtLeastOneLinkedLetters);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of the PronounceableWord library.
|
||||
*
|
||||
* (c) Loic Chardonnet
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE.txt
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
require_once dirname(__FILE__) . '/../../../src/PronounceableWord/DependencyInjectionContainer.php';
|
||||
|
||||
class PronounceableWord_Tests_DependencyInjectionContainerTest extends PHPUnit_Framework_TestCase {
|
||||
public function testClassNames() {
|
||||
$container = new PronounceableWord_DependencyInjectionContainer();
|
||||
|
||||
foreach ($container->classNames as $classType => $className) {
|
||||
$expectedClassName = 'PronounceableWord_' . $classType;
|
||||
$this->assertSame($expectedClassName, $className);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function testClassNamesAndInstances() {
|
||||
$container = new PronounceableWord_DependencyInjectionContainer();
|
||||
|
||||
foreach ($container->classNames as $classType => $className) {
|
||||
$getMethodName = 'get' . $classType;
|
||||
$instance = $container->{$getMethodName}();
|
||||
|
||||
$this->assertInstanceOf($className, $instance);
|
||||
}
|
||||
}
|
||||
|
||||
public function testConfigurations() {
|
||||
$container = new PronounceableWord_DependencyInjectionContainer();
|
||||
|
||||
foreach ($container->configurations as $className => $configurationInstance) {
|
||||
$configurationClassName = 'PronounceableWord_Configuration_' . $className;
|
||||
|
||||
$this->assertInstanceOf($configurationClassName, $configurationInstance);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of the PronounceableWord library.
|
||||
*
|
||||
* (c) Loic Chardonnet
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE.txt
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
require_once dirname(__FILE__) . '/../../../src/PronounceableWord/Configuration/LinkedLetters.php';
|
||||
require_once dirname(__FILE__) . '/../../../src/PronounceableWord/Configuration/LetterTypes.php';
|
||||
require_once dirname(__FILE__) . '/../../../src/PronounceableWord/Configuration/Generator.php';
|
||||
require_once dirname(__FILE__) . '/../../../src/PronounceableWord/LinkedLetters.php';
|
||||
require_once dirname(__FILE__) . '/../../../src/PronounceableWord/LetterTypes.php';
|
||||
require_once dirname(__FILE__) . '/../../../src/PronounceableWord/LastLettersConsecutiveTypes.php';
|
||||
require_once dirname(__FILE__) . '/../../../src/PronounceableWord/Generator.php';
|
||||
|
||||
class PronounceableWord_Tests_GeneratorTest extends PHPUnit_Framework_TestCase {
|
||||
public function testGeneratedLength() {
|
||||
$linkedLettersConfiguration = new PronounceableWord_Configuration_LinkedLetters();
|
||||
$letterTypesConfiguration = new PronounceableWord_Configuration_LetterTypes();
|
||||
$generatorConfiguration = new PronounceableWord_Configuration_Generator();
|
||||
|
||||
$linkedLetters = new PronounceableWord_LinkedLetters($linkedLettersConfiguration);
|
||||
$letterTypes = new PronounceableWord_LetterTypes($letterTypesConfiguration);
|
||||
$lastLettersConsecutiveTypes = new PronounceableWord_LastLettersConsecutiveTypes($letterTypes);
|
||||
|
||||
$maximumLength = 100;
|
||||
for ($length = 1; $length <= $maximumLength; $length++) {
|
||||
$generator = new PronounceableWord_Generator($linkedLetters, $letterTypes, $lastLettersConsecutiveTypes, $generatorConfiguration);
|
||||
|
||||
$generatedWord = $generator->generateWordOfGivenLength($length);
|
||||
|
||||
$this->assertEquals($length, strlen($generatedWord));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of the PronounceableWord library.
|
||||
*
|
||||
* (c) Loic Chardonnet
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE.txt
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
require_once dirname(__FILE__) . '/../../../src/PronounceableWord/Configuration/LetterTypes.php';
|
||||
require_once dirname(__FILE__) . '/../../../src/PronounceableWord/LetterTypes.php';
|
||||
require_once dirname(__FILE__) . '/../../../src/PronounceableWord/LastLettersConsecutiveTypes.php';
|
||||
|
||||
class PronounceableWord_Tests_LastLettersConsecutiveTypesTest extends PHPUnit_Framework_TestCase {
|
||||
public function testCountFromWordOfOneType() {
|
||||
$letterTypesConfiguration = new PronounceableWord_Configuration_LetterTypes();
|
||||
$letterTypes = new PronounceableWord_LetterTypes($letterTypesConfiguration);
|
||||
$lastLettersConsecutiveTypes = new PronounceableWord_LastLettersConsecutiveTypes($letterTypes);
|
||||
|
||||
foreach ($letterTypesConfiguration->letterTypesWithLetters as $letterType => $letters) {
|
||||
$maximumLetterNumber = strlen($letters);
|
||||
$word = '';
|
||||
for ($letterNumber = 1; $letterNumber < $maximumLetterNumber; $letterNumber++) {
|
||||
$letter = rand(0, strlen($letters) - 1);
|
||||
$word .= $letters[$letter];
|
||||
|
||||
$this->assertSame($letterNumber, $lastLettersConsecutiveTypes->countFromWord($word));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function testCountFromWordOfMultipleTypes() {
|
||||
$letterTypesConfiguration = new PronounceableWord_Configuration_LetterTypes();
|
||||
$letterTypes = new PronounceableWord_LetterTypes($letterTypesConfiguration);
|
||||
$lastLettersConsecutiveTypes = new PronounceableWord_LastLettersConsecutiveTypes($letterTypes);
|
||||
|
||||
foreach ($letterTypesConfiguration->letterTypesWithLetters as $letterType => $letters) {
|
||||
$maximumLetterNumber = strlen($letters);
|
||||
|
||||
foreach ($letterTypesConfiguration->letterTypesWithLetters as $otherLetterType => $otherLetters) {
|
||||
if ($otherLetterType != $letterType) {
|
||||
$word = $otherLetters;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for ($letterNumber = 1; $letterNumber < $maximumLetterNumber; $letterNumber++) {
|
||||
$letter = rand(0, strlen($letters) - 1);
|
||||
$word .= $letters[$letter];
|
||||
|
||||
$this->assertSame($letterNumber, $lastLettersConsecutiveTypes->countFromWord($word));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of the PronounceableWord library.
|
||||
*
|
||||
* (c) Loic Chardonnet
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE.txt
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
require_once dirname(__FILE__) . '/../../../src/PronounceableWord/Configuration/LetterTypes.php';
|
||||
require_once dirname(__FILE__) . '/../../../src/PronounceableWord/LetterTypes.php';
|
||||
|
||||
class PronounceableWord_Tests_LetterTypesTest extends PHPUnit_Framework_TestCase {
|
||||
public function testGetLetterType() {
|
||||
$configuration = new PronounceableWord_Configuration_LetterTypes();
|
||||
$letterTypes = new PronounceableWord_LetterTypes($configuration);
|
||||
|
||||
foreach ($configuration->letterTypesWithLetters as $letterType => $letters) {
|
||||
$maximumLetterIndex = strlen($letters);
|
||||
for ($letterIndex = 0; $letterIndex < $maximumLetterIndex; $letterIndex++) {
|
||||
$letter = $letters[$letterIndex];
|
||||
|
||||
$this->assertSame($letterType, $letterTypes->getLetterType($letter));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function testGetLettersOfGivenType() {
|
||||
$configuration = new PronounceableWord_Configuration_LetterTypes();
|
||||
$letterTypes = new PronounceableWord_LetterTypes($configuration);
|
||||
|
||||
foreach ($configuration->letterTypesWithLetters as $letterType => $letters) {
|
||||
$this->assertSame($letters, $letterTypes->getLettersOfGivenType($letterType));
|
||||
$maximumLetterIndex = strlen($letters);
|
||||
}
|
||||
}
|
||||
|
||||
public function testIsThereAtLeastTwoTypes() {
|
||||
$configuration = new PronounceableWord_Configuration_LetterTypes();
|
||||
$minimumLetterTypesNumber = 2;
|
||||
|
||||
$this->assertGreaterThanOrEqual($minimumLetterTypesNumber, $configuration->letterTypesWithLetters);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of the PronounceableWord library.
|
||||
*
|
||||
* (c) Loic Chardonnet
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE.txt
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
require_once dirname(__FILE__) . '/../../../src/PronounceableWord/Configuration/LinkedLetters.php';
|
||||
require_once dirname(__FILE__) . '/../../../src/PronounceableWord/LinkedLetters.php';
|
||||
|
||||
class PronounceableWord_Tests_LinkedLettersTest extends PHPUnit_Framework_TestCase {
|
||||
public function testPickLetter() {
|
||||
$configuration = new PronounceableWord_Configuration_LinkedLetters();
|
||||
$linkedLetters = new PronounceableWord_LinkedLetters($configuration);
|
||||
|
||||
$maximumTestNumber = 1000;
|
||||
for ($currentTestNumber = 0; $currentTestNumber < $maximumTestNumber; $currentTestNumber++) {
|
||||
$chosenLetter = $linkedLetters->pickLetter();
|
||||
|
||||
$this->assertArrayHasKey($chosenLetter, $configuration->lettersWithLinkedLetters);
|
||||
}
|
||||
}
|
||||
|
||||
public function testPickLinkedLetter() {
|
||||
$configuration = new PronounceableWord_Configuration_LinkedLetters();
|
||||
$linkedLetters = new PronounceableWord_LinkedLetters($configuration);
|
||||
|
||||
$maximumTestNumber = 1000;
|
||||
foreach ($configuration->lettersWithLinkedLetters as $currentLetter => $currentLinkedLetters) {
|
||||
for ($currentTestNumber = 0; $currentTestNumber < $maximumTestNumber; $currentTestNumber++) {
|
||||
$chosenLinkedLetter = $linkedLetters->pickLinkedLetter($currentLetter);
|
||||
|
||||
$isChosenLetterInLinkedLetters = strpos($currentLinkedLetters, $chosenLinkedLetter);
|
||||
|
||||
$this->assertNotEquals(false, $isChosenLetterInLinkedLetters);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function testPickLinkedLetterDifferentFromGivenLetters() {
|
||||
$configuration = new PronounceableWord_Configuration_LinkedLetters();
|
||||
$linkedLetters = new PronounceableWord_LinkedLetters($configuration);
|
||||
|
||||
$maximumTestNumber = 1000;
|
||||
foreach ($configuration->lettersWithLinkedLetters as $currentLetter => $currentLinkedLetters) {
|
||||
for ($currentTestNumber = 0; $currentTestNumber < $maximumTestNumber; $currentTestNumber++) {
|
||||
$chosenLinkedLetter = $linkedLetters->pickLinkedLetterDifferentFromGivenLetters($currentLetter, $currentLetter);
|
||||
|
||||
$isChosenLetterInLinkedLetters = strpos($currentLinkedLetters, $chosenLinkedLetter);
|
||||
|
||||
$isChosenLetterDifferentThanCurrentLetter = false;
|
||||
if ($chosenLinkedLetter !== $currentLetter) {
|
||||
$isChosenLetterDifferentThanCurrentLetter = true;
|
||||
}
|
||||
|
||||
$isChosenLetterValid = false;
|
||||
if (false !== $isChosenLetterInLinkedLetters && true === $isChosenLetterDifferentThanCurrentLetter) {
|
||||
$isChosenLetterValid = true;
|
||||
}
|
||||
|
||||
$this->assertTrue($isChosenLetterValid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,10 +22,10 @@ function error($status, $text) {
|
|||
|
||||
/**
|
||||
* print all mails for the given $user.
|
||||
* @param $username string username
|
||||
* @param $address string email address
|
||||
* @return array
|
||||
*/
|
||||
function print_emails($username, $address) {
|
||||
function get_emails($address) {
|
||||
global $mailbox;
|
||||
|
||||
// Search for mails with the recipient $address in TO or CC.
|
||||
|
@ -34,8 +34,7 @@ function print_emails($username, $address) {
|
|||
$mail_ids = array_merge($mailsIdsTo, $mailsIdsCc);
|
||||
|
||||
$emails = _load_emails($mail_ids, $address);
|
||||
header('Content-type: application/json');
|
||||
print(json_encode(array("mails" => $emails, 'username' => $username, 'address' => $address)));
|
||||
return $emails;
|
||||
}
|
||||
|
||||
|
||||
|
@ -126,6 +125,25 @@ function _clean_username($username) {
|
|||
return preg_replace('/[^A-Za-z0-9_.+-]/', "", $username); // remove special characters
|
||||
}
|
||||
|
||||
function _clean_domain($username) {
|
||||
$username = strtolower($username);
|
||||
$username = preg_replace('/^.*@/', "", $username); // remove part before @
|
||||
return preg_replace('/[^A-Za-z0-9_.+-]/', "", $username); // remove special characters
|
||||
}
|
||||
|
||||
function redirect_to_random($domains) {
|
||||
$wordLength = rand(3, 8);
|
||||
$container = new PronounceableWord_DependencyInjectionContainer();
|
||||
$generator = $container->getGenerator();
|
||||
$word = $generator->generateWordOfGivenLength($wordLength);
|
||||
$nr = rand(51, 91);
|
||||
$name = $word . $nr;
|
||||
|
||||
$domain = $domains[array_rand($domains)];
|
||||
|
||||
header("location: ?address=$name@$domain");
|
||||
}
|
||||
|
||||
/**
|
||||
* deletes messages older than X days.
|
||||
*/
|
||||
|
@ -139,30 +157,11 @@ function delete_old_messages() {
|
|||
$mailbox->expungeDeletedMails();
|
||||
}
|
||||
|
||||
// Never cache requests:
|
||||
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
|
||||
header("Cache-Control: post-check=0, pre-check=0", false);
|
||||
header("Pragma: no-cache");
|
||||
|
||||
if (isset($_GET['username'])) {
|
||||
// perform common validation:
|
||||
$username = _clean_username($_GET['username']);
|
||||
if (strlen($username) === 0) {
|
||||
error(400, 'invalid username');
|
||||
}
|
||||
$address = $username . "@" . $config['mailHostname'];
|
||||
|
||||
// simple router:
|
||||
if (isset($_GET['download_email_id'])) {
|
||||
download_email($_GET['download_email_id'], $address);
|
||||
} else if (isset($_GET['delete_email_id'])) {
|
||||
delete_email($_GET['delete_email_id'], $address);
|
||||
} else {
|
||||
print_emails($username, $address);
|
||||
}
|
||||
} else {
|
||||
error(400, 'invalid action');
|
||||
}
|
||||
//
|
||||
//// Never cache requests:
|
||||
//header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
|
||||
//header("Cache-Control: post-check=0, pre-check=0", false);
|
||||
//header("Pragma: no-cache");
|
||||
|
||||
// run on every request
|
||||
delete_old_messages();
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
[ec-stickyfill] {
|
||||
position: -webkit-sticky;
|
||||
position: sticky;
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
[ec-stickyfill]:before,
|
||||
[ec-stickyfill]:after {
|
||||
content: '';
|
||||
display: table;
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
/**
|
||||
* An Angular directive for stickyfill (position sticky polyfill)
|
||||
*
|
||||
* @version v0.1.0 - 2016-08-31
|
||||
* @author Corey Wilson <corey@eastcodes.com>
|
||||
* @license Unlicense, http://unlicense.org/
|
||||
*/
|
||||
!function(e,i){"use strict";if("function"==typeof define&&define.amd)define(["angular","stickyfill"],i);else{if("undefined"==typeof module||"object"!=typeof module.exports)return i(e.angular,e.Stickyfill);module.exports=i(require("angular"),require("stickyfill"))}}(window,function(e,i){"use strict";function t(){function e(e,t,n){if("object"!=typeof i)throw new Error("stickyfill.js not loaded");i.add(t[0]),e.$on("$destroy",function(){i.remove(t[0])})}var t={link:e,restrict:"A"};return t}if("function"==typeof i)var i=i();var n="ec.stickyfill";return e.module(n,[]).directive("ecStickyfill",t),n});
|
|
@ -1,137 +0,0 @@
|
|||
// config:
|
||||
var reload_interval_ms = 10000;
|
||||
var backend_url = './backend.php';
|
||||
|
||||
function generateRandomUsername() {
|
||||
var username = "";
|
||||
if (chance.bool()) {
|
||||
username += chance.first();
|
||||
if (chance.bool()) {
|
||||
username += chance.last();
|
||||
}
|
||||
} else {
|
||||
username += chance.word({syllables: 3})
|
||||
}
|
||||
if (chance.bool()) {
|
||||
username += chance.integer({min: 30, max: 99});
|
||||
}
|
||||
return username.toLowerCase();
|
||||
}
|
||||
|
||||
var app = angular.module('app', ["ngSanitize"]);
|
||||
|
||||
// http://stackoverflow.com/a/20033625/79461
|
||||
app.filter("nl2br", function () {
|
||||
return function (data) {
|
||||
if (!data) return data;
|
||||
return data.replace(/\r?\n/g, '<br/>');
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// http://stackoverflow.com/a/20033625/79461
|
||||
app.filter("autolink", function () {
|
||||
return function (data) {
|
||||
return Autolinker.link(data, {truncate: {length: 50, location: 'middle', newWindow: true}});
|
||||
}
|
||||
});
|
||||
|
||||
app.controller('MailboxController', ["$interval", "$http", "$log", function ($interval, $http, $log) {
|
||||
var self = this;
|
||||
|
||||
self.backend_url = backend_url;
|
||||
|
||||
self.updateUsername = function (username) {
|
||||
username = username.replace(/[@].*$/, ''); // remove part after "@"
|
||||
if (self.username !== username) {
|
||||
// changed
|
||||
self.username = username;
|
||||
hasher.setHash(self.username);
|
||||
|
||||
if (self.username.length > 0) {
|
||||
self.address = self.username; // use username until real address has been loaded
|
||||
self.updateMails();
|
||||
} else {
|
||||
self.randomize();
|
||||
}
|
||||
}
|
||||
self.inputFieldUsername = self.username;
|
||||
};
|
||||
|
||||
|
||||
self.randomize = function () {
|
||||
self.updateUsername(generateRandomUsername());
|
||||
};
|
||||
|
||||
|
||||
self.onHashChange = function (hash) {
|
||||
self.updateUsername(hash);
|
||||
};
|
||||
|
||||
self.$onInit = function () {
|
||||
hasher.changed.add(self.onHashChange.bind(self));
|
||||
hasher.initialized.add(self.onHashChange.bind(self)); //add initialized listener (to grab initial value in case it is already set)
|
||||
hasher.init(); //initialize hasher (start listening for history changes)
|
||||
|
||||
$interval(self.updateMails, reload_interval_ms);
|
||||
};
|
||||
|
||||
self.updateMails = function () {
|
||||
if (self.username) {
|
||||
self.loadEmailsAsync(self.username);
|
||||
}
|
||||
};
|
||||
|
||||
self.loadEmailsAsync = function (username) {
|
||||
$http.get(backend_url, {params: {username: username}})
|
||||
.then(function successCallback(response) {
|
||||
if (response.data.mails) {
|
||||
self.error = null;
|
||||
self.mails = response.data.mails;
|
||||
self.address = response.data.address;
|
||||
self.username = response.data.username;
|
||||
if (self.inputFieldUsername === self.username) {
|
||||
self.inputFieldUsername = self.address;
|
||||
}
|
||||
} else {
|
||||
self.error = {
|
||||
title: "JSON_ERROR",
|
||||
desc: "The JSON from the response can not be read.",
|
||||
detail: response
|
||||
};
|
||||
$log.error(response);
|
||||
}
|
||||
}, function errorCallback(response) {
|
||||
$log.error(response, this);
|
||||
self.error = {
|
||||
title: "HTTP_ERROR",
|
||||
desc: "There is a problem with loading the data. (HTTP_ERROR).",
|
||||
detail: response
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
self.deleteMail = function (mail, index) {
|
||||
// instantly remove from frontend.
|
||||
self.mails.splice(index, 1);
|
||||
|
||||
// remove on backend.
|
||||
var firstTo = Object.keys(mail.to)[0];
|
||||
$http.get(backend_url, {params: {username: firstTo, delete_email_id: mail.id}})
|
||||
.then(
|
||||
function successCallback(response) {
|
||||
self.updateMails();
|
||||
},
|
||||
function errorCallback(response) {
|
||||
$log.error(response, this);
|
||||
self.error = {
|
||||
title: "HTTP_ERROR",
|
||||
desc: "There is a problem with deleting the mail. (HTTP_ERROR).",
|
||||
detail: response
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
// Initial load
|
||||
self.updateMails()
|
||||
}]);
|
|
@ -3,22 +3,20 @@
|
|||
// set your time zone:
|
||||
date_default_timezone_set('Europe/Paris');
|
||||
|
||||
// enable while testing:
|
||||
error_reporting(E_ALL);
|
||||
// enable in production:
|
||||
// error_reporting(0);
|
||||
error_reporting(0);
|
||||
|
||||
// enable while testing:
|
||||
//error_reporting(E_ALL);
|
||||
|
||||
// configure this option if you want to allow requests from clients from other domains:
|
||||
// see https://en.wikipedia.org/wiki/Cross-origin_resource_sharing
|
||||
// header("Access-Control-Allow-Origin: *");
|
||||
|
||||
// Change IMAP settings (check SSL flags on http://php.net/manual/en/function.imap-open.php)
|
||||
$config['imap']['url'] = '{example.com/imap/ssl}INBOX';
|
||||
$config['imap']['username'] = "test";
|
||||
$config['imap']['password'] = "test";
|
||||
$config['imap']['url'] = '{imap.example.com/imap/ssl}INBOX';
|
||||
$config['imap']['username'] = "myuser";
|
||||
$config['imap']['password'] = "mypassword";
|
||||
|
||||
// email domain, usually different from imap hostname:
|
||||
$config['mailHostname'] = "example.com";
|
||||
// email domains, usually different from imap hostname:
|
||||
$config['domains'] = array('mydomain.com', 'example.com');
|
||||
|
||||
// When to delete old messages?
|
||||
$config['delete_messages_older_than'] = '30 days ago';
|
150
src/index.html
150
src/index.html
|
@ -1,150 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="de" ng-app="app" ng-strict-di>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Mailbox</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
<meta name="description" content="Mailbox">
|
||||
<link rel="shortcut icon" href="favicon.gif" type="image/x-icon">
|
||||
<link rel="stylesheet" href="client-libs/style.css">
|
||||
<link rel="stylesheet" href="client-libs/spinner.css">
|
||||
<link rel="stylesheet" href="client-libs/angular-stickyfill-0.1.0/angular-stickyfill.css">
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/css/bootstrap.min.css"
|
||||
integrity="sha384-AysaV+vQoT3kOAXZkl02PThvDr8HYKPZhNT5h/CXfBThSRXQ6jW5DO2ekP5ViFdi" crossorigin="anonymous">
|
||||
</head>
|
||||
<body>
|
||||
<div ng-controller="MailboxController as $ctrl" ng-cloak>
|
||||
<header>
|
||||
<div class="container">
|
||||
|
||||
<form ng-submit="$ctrl.updateUsername($ctrl.inputFieldUsername)">
|
||||
|
||||
<small id="emailHelp" class="form-text text-muted">
|
||||
You have <span class="tag tag-pill tag-default">{{$ctrl.mails.length}}</span> mails in your
|
||||
mailbox:
|
||||
</small>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-8">
|
||||
|
||||
<input id="inputFieldUsername" ng-model="$ctrl.inputFieldUsername"
|
||||
placeholder="new username"
|
||||
type="text" class="form-control form-control-lg" onclick="this.select()"/>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<button id="openRandomButton" ng-click="$ctrl.randomize()" type="button"
|
||||
class="btn btn-outline-primary">open random
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<div class="container min-height">
|
||||
<div ng-if="$ctrl.error" class="alert alert-danger" role="alert">
|
||||
<p><strong>Sorry, there was a problem. </strong></p>
|
||||
<p> {{$ctrl.error.desc}} </p>
|
||||
<div>
|
||||
<pre>{{$ctrl.error.detail|json}}</pre>
|
||||
</div>
|
||||
<p> If you are the developer you might want to check the developer tools console of your web
|
||||
browser and your php error logs. </p>
|
||||
</div>
|
||||
|
||||
<div ng-if="$ctrl.username && $ctrl.mails.length == 0">
|
||||
<div class="card waiting-screen">
|
||||
<div class="card-block">
|
||||
<p class="lead">Your mailbox <strong>{{$ctrl.address}}</strong> is ready. </p>
|
||||
<p>Emails will appear here automatically. They will be deleted after 30 days.</p>
|
||||
<div class="spinner">
|
||||
<div class="rect1"></div>
|
||||
<div class="rect2"></div>
|
||||
<div class="rect3"></div>
|
||||
<div class="rect4"></div>
|
||||
<div class="rect5"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-if="$ctrl.username" ng-repeat="mail in $ctrl.mails | orderBy:'-date' track by $index"
|
||||
class="email-table">
|
||||
|
||||
<div class="card email">
|
||||
<div class="card-block header-shadow sticky-header" ec-stickyfill ng-init="htmlTabActive=false">
|
||||
<div class="row">
|
||||
<div class="col-sm-8">
|
||||
<h3 class="card-title">{{mail.subject}}</h3>
|
||||
</div>
|
||||
<div class="col-sm-4 text-right">
|
||||
<form class="form-inline float-xs-right">
|
||||
|
||||
<button ng-show="htmlTabActive" class="btn btn-outline-info btn-sm "
|
||||
ng-click="htmlTabActive=false">show text
|
||||
</button>
|
||||
<button ng-show="mail.textHtml && !htmlTabActive"
|
||||
class="btn btn-outline-info btn-sm"
|
||||
ng-click="htmlTabActive=true">show html
|
||||
</button>
|
||||
|
||||
<a role="button" class="btn btn-sm btn-outline-primary "
|
||||
href="{{$ctrl.backend_url}}?download_email_id={{mail.id}}&username={{$ctrl.username}}"
|
||||
download="true">Download
|
||||
</a>
|
||||
|
||||
<button ng-click="$ctrl.deleteMail(mail, $index)" type="button"
|
||||
class="btn btn-sm btn-outline-danger">Delete
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-8">
|
||||
<h6 class="card-subtitle mt-1 text-muted">{{mail.fromName}}
|
||||
<{{mail.fromAddress}}></h6>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<h6 class="card-subtitle mt-1 text-muted" style="text-align: right">{{mail.date}}</h6>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-block">
|
||||
<h6 class="card-subtitle text-muted">To: {{mail.toString}}</h6>
|
||||
<h6 ng-if="mail.cc" ng-repeat="(address,name) in mail.cc" class="card-subtitle text-muted">CC:
|
||||
{{address}}</h6>
|
||||
|
||||
<div class="mt-2 card-text">
|
||||
<div ng-if="!htmlTabActive" ng-bind-html="mail.textPlain | nl2br | autolink "></div>
|
||||
<div ng-if="htmlTabActive" ng-bind-html="mail.textHtml"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<p>Powered by <a href="https://github.com/synox/disposable-mailbox"><strong>synox/disposable-mailbox</strong></a>
|
||||
| <a href="https://github.com/synox/disposable-mailbox"><span class="octicon octicon-mark-github"></span> Fork
|
||||
me on github</a></p>
|
||||
</footer>
|
||||
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-sanitize.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/autolinker/1.2.0/Autolinker.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/chance/1.0.4/chance.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/stickyfill/1.1.4/stickyfill.min.js"></script>
|
||||
<script src="client-libs/angular-stickyfill-0.1.0/angular-stickyfill.js"></script>
|
||||
<script src="client-libs/index.js"></script>
|
||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/js-signals/1.0.0/js-signals.js"></script>
|
||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/hasher/1.2.0/hasher.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
240
src/index.php
Normal file
240
src/index.php
Normal file
|
@ -0,0 +1,240 @@
|
|||
<?php
|
||||
require_once('backend.php');
|
||||
|
||||
|
||||
if (isset($_GET['random'])) {
|
||||
redirect_to_random($config['domains']);
|
||||
die();
|
||||
} elseif (isset($_GET['username']) && isset($_GET['domain'])) {
|
||||
$username = filter_input(INPUT_GET, 'username', FILTER_SANITIZE_EMAIL);
|
||||
$domain = filter_input(INPUT_GET, 'domain', FILTER_SANITIZE_EMAIL);
|
||||
header("location: ?address=$username@$domain");
|
||||
die();
|
||||
} elseif (!isset($_GET['address'])) {
|
||||
error(400, 'invalid action');
|
||||
} else {
|
||||
// perform common validation:
|
||||
$address = filter_input(INPUT_GET, 'address', FILTER_SANITIZE_EMAIL);
|
||||
$username = _clean_username($address);
|
||||
$userDomain = _clean_domain($address);
|
||||
if (strlen($address) === 0) {
|
||||
error(400, 'invalid username');
|
||||
}
|
||||
if (strlen($userDomain) === 0 || !in_array($userDomain, $config['domains'])) {
|
||||
error(400, 'invalid domain');
|
||||
}
|
||||
|
||||
// simple router:
|
||||
if (isset($_GET['download_email_id'])) {
|
||||
download_email($_GET['download_email_id'], $address);
|
||||
die();
|
||||
}
|
||||
if (isset($_GET['delete_email_id'])) {
|
||||
$delete_email_id = filter_input(INPUT_GET, 'delete_email_id', FILTER_SANITIZE_NUMBER_INT);
|
||||
delete_email($delete_email_id, $address);
|
||||
}
|
||||
// print emails:
|
||||
$emails = get_emails($address);
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Mailbox <?php echo $address ?></title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/css/bootstrap.min.css"
|
||||
integrity="sha384-AysaV+vQoT3kOAXZkl02PThvDr8HYKPZhNT5h/CXfBThSRXQ6jW5DO2ekP5ViFdi" crossorigin="anonymous">
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<link rel="stylesheet" href="spinner.css">
|
||||
<script src="turbolinks.js"></script>
|
||||
<meta name="turbolinks-cache-control" content="no-preview">
|
||||
|
||||
<script>
|
||||
// https://stackoverflow.com/a/44353026
|
||||
var reloadWithTurbolinks = (function () {
|
||||
var scrollPosition;
|
||||
|
||||
function reload() {
|
||||
scrollPosition = [window.scrollX, window.scrollY];
|
||||
Turbolinks.visit(window.location.toString(), {action: 'replace'})
|
||||
}
|
||||
|
||||
document.addEventListener('turbolinks:load', function () {
|
||||
if (scrollPosition) {
|
||||
window.scrollTo.apply(window, scrollPosition);
|
||||
scrollPosition = null
|
||||
}
|
||||
});
|
||||
|
||||
return reload
|
||||
})();
|
||||
|
||||
|
||||
setInterval(function () {
|
||||
reloadWithTurbolinks();
|
||||
}, 10000)
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
|
||||
<body data-turbolinks="false">
|
||||
|
||||
<header>
|
||||
<div class="container">
|
||||
<small class="form-text text-muted">
|
||||
change username:
|
||||
</small>
|
||||
|
||||
<form action="?" method="get">
|
||||
<div class="form-group row">
|
||||
|
||||
<div class="col-sm-4">
|
||||
<input id="username" data-turbolinks-permanent class="form-control form-control-lg" name="username"
|
||||
value="<?php echo $username ?>">
|
||||
</div>
|
||||
<div class="col-sm-3">
|
||||
<select id="domain" data-turbolinks-permanent class="form-control form-control-lg" name="domain">
|
||||
<?php
|
||||
foreach ($config['domains'] as $domain) {
|
||||
$selected = $domain === $userDomain ? ' selected ' : '';
|
||||
print "<option value='$domain' $selected>@$domain</option>";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-3 random-column">
|
||||
<span>or </span>
|
||||
<a role="button" href="?random=true" class="btn btn-outline-primary">generate random
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
<main>
|
||||
<div class="container min-height">
|
||||
|
||||
<?php
|
||||
if (empty($emails)) {
|
||||
?>
|
||||
<div>
|
||||
<div class="card waiting-screen">
|
||||
<div class="card-block">
|
||||
<p class="lead">Your mailbox <strong
|
||||
><?php echo $address ?></strong> is ready. </p>
|
||||
<p>Emails will appear here automatically. They will be deleted after 30
|
||||
days.</p>
|
||||
<div class="spinner">
|
||||
<div class="rect1"></div>
|
||||
<div class="rect2"></div>
|
||||
<div class="rect3"></div>
|
||||
<div class="rect4"></div>
|
||||
<div class="rect5"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
} else {
|
||||
|
||||
foreach ($emails as $email) {
|
||||
|
||||
?>
|
||||
|
||||
<div class="email-table">
|
||||
|
||||
<div class="card email">
|
||||
<div class="card-block header-shadow sticky-header">
|
||||
<div class="row">
|
||||
<div class="col-sm-8">
|
||||
<h3 class="card-title">
|
||||
<?php echo filter_var($email->subject, FILTER_SANITIZE_SPECIAL_CHARS); ?>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="col-sm-4 text-right">
|
||||
<form class="form-inline float-xs-right">
|
||||
|
||||
<!-- <button class="btn btn-outline-info btn-sm">show html-->
|
||||
<!-- </button>-->
|
||||
|
||||
<a class="btn btn-sm btn-outline-primary " download="true"
|
||||
role="button"
|
||||
href="?download_email_id=<?php echo filter_var($email->id, FILTER_VALIDATE_INT); ?>&address=<?php echo $address ?>">Download
|
||||
</a>
|
||||
|
||||
<!-- <button class="btn btn-sm btn-outline-danger" type="button">-->
|
||||
<!-- Delete-->
|
||||
<!-- </button>-->
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-8">
|
||||
<h6 class="card-subtitle mt-1 text-muted">
|
||||
<?php
|
||||
echo filter_var($email->fromName, FILTER_SANITIZE_SPECIAL_CHARS);
|
||||
echo ' <';
|
||||
echo filter_var($email->fromAddress, FILTER_SANITIZE_SPECIAL_CHARS);
|
||||
echo '>';
|
||||
?>
|
||||
</h6>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<h6 class="card-subtitle mt-1 text-muted"
|
||||
style="text-align: right">
|
||||
<?php echo filter_var($email->date, FILTER_SANITIZE_SPECIAL_CHARS); ?>
|
||||
</h6>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-block">
|
||||
<h6 class="card-subtitle text-muted">
|
||||
To: <?php echo filter_var($email->toString, FILTER_SANITIZE_SPECIAL_CHARS); ?></h6>
|
||||
|
||||
<?php
|
||||
foreach ($email->cc as $cc) {
|
||||
print "<h6 class='card-subtitle text-muted'>CC: " . filter_var($cc, FILTER_SANITIZE_SPECIAL_CHARS) . "</h6>";
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
<div class="mt-2 card-text">
|
||||
<!-- TODO: switch between html and plaintext -->
|
||||
<div>
|
||||
<!-- TODO: applyAutolink
|
||||
TODO: applyNewlines -->
|
||||
<?php $text = filter_var($email->textPlain, FILTER_SANITIZE_SPECIAL_CHARS);
|
||||
echo str_replace(' ', '<br />', $text);
|
||||
?>
|
||||
|
||||
</div>
|
||||
<div *ngIf="htmlTabActive">
|
||||
<!-- TODO: stripHtml(mail.textHtml) -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
|
@ -19,22 +19,18 @@ div.min-height {
|
|||
|
||||
header {
|
||||
background-color: #D9E2E9;
|
||||
/* leave some space on top */
|
||||
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
#openRandomButton {
|
||||
/* center vertically */
|
||||
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.email-table > .email {
|
||||
border-top: 5px solid #7C96AB;
|
||||
|
||||
/* idea: card shadow arround:
|
||||
see https://blog.alexdevero.com/mastering-card-design-with-bootstrap-4/
|
||||
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
|
||||
*/
|
||||
}
|
||||
|
||||
.header-shadow {
|
||||
|
@ -47,7 +43,6 @@ header {
|
|||
background-color: white;
|
||||
}
|
||||
|
||||
|
||||
.waiting-screen {
|
||||
padding: 40px 15px;
|
||||
text-align: center;
|
||||
|
@ -57,3 +52,7 @@ div.min-height {
|
|||
min-height: 400px;
|
||||
}
|
||||
|
||||
.random-column {
|
||||
border-left: 1px dashed #333;
|
||||
|
||||
}
|
6
src/turbolinks.js
Normal file
6
src/turbolinks.js
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue