Skip to content

Reworking API internals #24

@Blackskyliner

Description

@Blackskyliner

I would like to discuss and track changes to the project in this ticket regarding an update to the internals and adding the possibility for more interchangeable Components like PSR-6 Caching without breaking legacy compatibility as mentioned in #18.

I extracted the public facing API of the Syllable class into an interface which one of the new components would have to adhere to so we keep compatibility.

<?php

namespace Vanderlee\PhpSyllable;

/**
 * This interface describes the Syllable class prior X.Y.Z
 * 
 * To keep compatibility with already existing implementations into applications
 * this interface is a necessary evil. It will make sure that the public facing
 * class will at least adhere to the promise of pre X.Y.Z versions regarding the
 * public API.
 * 
 * The internals will be reworked to a whole new base w/o breaking old usages.
 * PHP 5.6 Compatibility should be kept until EOL or have a version_compare switch.
 */
interface LegacyInterface{
    // Global Configuration statics
    public static function setCacheDir($dir);
    public static function setEncoding($encoding = null);
    public static function setLanguageDir($dir);

    // Configurable Language
    public function setLanguage($language);

    // Hypen-to-use Configuration
    public function setHyphen(Syllable_Hypen_Interface $hyphen);
    public function getHyphen();

    // Cache Configuration
    public function setCache(Syllable_Cache_Interface $Cache = null);
    public function getCache();

    // Source configuration
    public function setSource(Syllable_Source_Interface $Source);
    public function getSource();

    // Hypening Configuration
    public function setMinWordLength($length = 0);
    public function getMinWordLength();

    // HTML Interface
    public function excludeAll();
    public function excludeElement($elements);
    public function excludeAttribute($attributes, $value = null);
    public function excludeXpath($queries);
    public function includeElement($elements);
    public function includeAttribute($attributes, $value = null);
    public function includeXpath($queries);
    public function hyphenateHtml($html);

    // Text interface
    public function splitWord($word);
    public function splitText($text);
    public function hyphenateWord($word);
    public function hyphenateText($text);

    // Stats
    public function histogramText($text);
    public function countWordsText($text);
    public function countSyllablesText($text);
    public function countPolysyllablesText($text);

    // Already deprecated!
    public function setTreshold($treshold);
    public function getTreshold();
}

Each commented block of functions should get it's own implementation handler classes. Like the hyphening algorithm and the html processing etc. So we clean all the logic from that "master class" we currently have.

To tackle the problem with the class namespacing for legacy projects I would suggest modifying the project autoloader. There we could, a bit like the Twig project does in their class files, register class_alias to the old Syllable class names. We also need to add at least PSR-0 or PSR-4 compatible autoloading for those not using composer.

/**
* Classloader for the library
* @param string $class
*/
function Syllable_autoloader($class) {
	// The new classes will reside in PROJECT_ROOT/src/
	// Whereas the \\Vanderlee\\PhpSyllable namespace is the root namespace of src/
	// So a \\Vanderlee\\PhpSyllable\\Hyphen\\Dash would be in src/Hypen/Dash.php

	$classWithoutRootNamespace = str_replace('Vanderlee\\PhpSyllable\\', '', $class);
	$classFile = __DIR__ 
		. DIRECTORY_SEPARATOR . '..' 
		. DIRECTORY_SEPARATOR . 'src' 
		. DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $classWithoutRootNamespace).'.php';

	if (file_exists($classFile)) {
		require $classFile;

		return true; // This will help class_exists to work properly
	}
	
	return false; // This will help class_exists to work properly
}

spl_autoload_register('Syllable_autoloader');

// Bind old Class Names to be backwards compatible
// All files in /classes will be deleted and bound to their new equivalent
// which will then reside within /src
class_alias('\\Vanderlee\\PhpSyllable\\Syllable', '\\Syllable');

I would say this whole rework should have multiple stages.

  1. Maybe write some more tests so we get a better coverage and have a more solid refactoring base to test against.
  2. Rewrite the class structure to the new namespacing and greenify all tests w/o adjusting them
  3. Deprecate the usage of the old "master class" interface and document the proper but more configuration-verbose wiring of all the separate classes into a less public interfaced service class. (like it should really only have a hyphenate($text, $language) or so the rest should be initialization work, where as languages would have to be registered to be known in the proccess)

What are your thoughts on this? Did I miss something important? Or would you tackle the whole problem in another way?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions