Passed
Push — master ( d8dc61...dfdb64 )
by Sebastian
09:05
created

Syntax::createTranslator()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 34
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 20
c 0
b 0
f 0
dl 0
loc 34
rs 9.6
cc 3
nc 3
nop 1
1
<?php
2
/**
3
 * File containing the {@see \Mailcode\Translator\Syntax} class.
4
 *
5
 * @package Mailcode
6
 * @subpackage Translator
7
 * @see \Mailcode\Translator\Syntax
8
 */
9
10
declare(strict_types=1);
11
12
namespace Mailcode\Translator;
13
14
use Mailcode\Mailcode_Commands_Command;
15
use Mailcode\Mailcode_Exception;
16
use Mailcode\Mailcode_Parser_Safeguard;
17
use Mailcode\Mailcode_Translator_Exception;
18
19
/**
20
 * Abstract base class for a translator syntax, allowing the translation
21
 * of mailcode commands into this syntax.
22
 *
23
 * @package Mailcode
24
 * @subpackage Translator
25
 * @author Sebastian Mordziol <[email protected]>
26
 */
27
class Syntax
28
{
29
    public const ERROR_UNKNOWN_COMMAND_TYPE = 50401;
30
    public const ERROR_INVALID_COMMAND_INSTANCE = 50402;
31
    
32
   /**
33
    * @var string
34
    */
35
    protected string $typeID;
36
    
37
    public function __construct(string $typeID)
38
    {
39
        $this->typeID = $typeID;
40
    }
41
    
42
   /**
43
    * Retrieves the syntax's type ID, e.g. "ApacheVelocity".
44
    * @return string
45
    */
46
    public function getTypeID() : string
47
    {
48
        return $this->typeID;
49
    }
50
    
51
   /**
52
    * Translates a single command to the target syntax.
53
    * 
54
    * @param Mailcode_Commands_Command $command
55
    * @throws Mailcode_Translator_Exception
56
    * @return string
57
    */
58
    public function translateCommand(Mailcode_Commands_Command $command) : string
59
    {
60
        return $this->createTranslator($command)->translate($command);
61
    }
62
63
    /**
64
     * @param Mailcode_Commands_Command $command
65
     * @return BaseCommandTranslation
66
     * @throws Mailcode_Translator_Exception
67
     */
68
    public function createTranslator(Mailcode_Commands_Command $command) : BaseCommandTranslation
69
    {
70
        $class = sprintf(
71
            __CLASS__ .'\%s\%sTranslation',
72
            $this->getTypeID(),
73
            $command->getID()
74
        );
75
76
        if(!class_exists($class))
77
        {
78
            throw new Mailcode_Translator_Exception(
79
                sprintf('Unknown command %s in translator', $command->getID()),
80
                sprintf(
81
                    'The class [%s] does not exist.',
82
                    $class
83
                ),
84
                self::ERROR_UNKNOWN_COMMAND_TYPE
85
            );
86
        }
87
        
88
        $translator = new $class($command);
89
90
        if($translator instanceof BaseCommandTranslation)
91
        {
92
            return $translator;
93
        }
94
95
        throw new Mailcode_Translator_Exception(
96
            'Invalid translator command instance.',
97
            sprintf(
98
                'The class [%s] does not extend the base translator command class.',
99
                get_class($translator)
100
            ),
101
            self::ERROR_INVALID_COMMAND_INSTANCE
102
        );
103
    }
104
105
    /**
106
     * Translates all safeguarded commands in the subject string to the
107
     * target syntax in one go.
108
     *
109
     * @param Mailcode_Parser_Safeguard $safeguard
110
     * @return string
111
     * @throws Mailcode_Exception
112
     * @throws Mailcode_Translator_Exception
113
     */
114
    public function translateSafeguard(Mailcode_Parser_Safeguard $safeguard) : string
115
    {
116
        $subject = $safeguard->makeSafe();
117
        
118
        if(!$safeguard->hasPlaceholders())
119
        {
120
            return $subject;
121
        }
122
        
123
        $placeholders = $safeguard->getPlaceholdersCollection()->getAll();
124
        
125
        $replaces = array();
126
        
127
        foreach($placeholders as $placeholder)
128
        {
129
            $command = $placeholder->getCommand();
130
131
            $replaces[$placeholder->getReplacementText()] = $this->translateCommand($command);
132
        }
133
            
134
        return str_replace(array_keys($replaces), array_values($replaces), $subject);
135
    }
136
}
137