1+ <?php
2+
3+ namespace AIMLConverter ;
4+
5+ class AIMLConverter
6+ {
7+ private $ document = null ;
8+
9+ public function __construct ()
10+ {
11+ $ this ->document = new \DOMDocument ('1.0 ' , 'UTF-8 ' );
12+
13+ $ this ->document ->preserveWhiteSpace = false ;
14+ $ this ->document ->formatOutput = true ;
15+ }
16+
17+ /**
18+ * Creates a .CSV file from an AIML file
19+ *
20+ * @param string $filename Name of the AIML file
21+ * @return bool
22+ */
23+ public function aiml2csv ($ filename )
24+ {
25+ if (!is_readable ($ filename )) {
26+ throw new \InvalidArgumentException ('File was not found or is not readable ' );
27+ }
28+
29+ $ ext = pathinfo ($ filename , PATHINFO_EXTENSION );
30+
31+ if (!in_array ($ ext , ['xml ' , 'aiml ' ]) ||
32+ mime_content_type ($ filename ) !== 'application/xml '
33+ ) {
34+ throw new \InvalidArgumentException ('Wrong MIME content type or file extension ' );
35+ }
36+
37+ $ this ->document ->load ($ filename );
38+
39+ $ csv = [];
40+
41+ /** @var \DOMElement $category */
42+ foreach ($ this ->document ->getElementsByTagName ('category ' ) as $ line => $ category )
43+ {
44+ $ csv [$ line ][] = 0 ;
45+
46+ $ pattern = $ that = $ topic = $ template = null ;
47+
48+ /** @var \DOMElement $childNode */
49+ foreach ($ category ->childNodes as $ childNode ) {
50+ $ xml = $ childNode ->ownerDocument ->saveXML ($ childNode );
51+
52+ switch ($ childNode ->nodeName ) {
53+ case 'pattern ' :
54+ /** @noinspection All */
55+ $ pattern = strip_tags ($ xml , '<set><bot><name> ' );
56+ break ;
57+ case 'that ' :
58+ /** @noinspection All */
59+ $ that = strip_tags ($ xml , '<set><bot><name> ' );
60+ break ;
61+ case 'topic ' :
62+ /** @noinspection All */
63+ $ topic = strip_tags ($ xml , '<set><bot><name> ' );
64+ break ;
65+ case 'template ' :
66+ $ template = substr ($ xml , 10 , -11 );
67+ break ;
68+ }
69+ }
70+
71+ $ template = trim ($ template );
72+ $ template = str_replace ([PHP_EOL , ', ' ], ['#Newline ' , '#Comma ' ], $ template );
73+
74+ $ csv [$ line ][] = $ pattern ;
75+ $ csv [$ line ][] = ($ that !== null ) ? $ that : '* ' ;
76+
77+ if ($ category ->parentNode ->nodeName === 'topic ' ) {
78+ $ csv [$ line ][] = $ category ->parentNode ->getAttribute ('name ' );
79+ }
80+ else {
81+ $ csv [$ line ][] = ($ topic !== null ) ? $ topic : '* ' ;
82+ }
83+
84+ $ csv [$ line ][] = $ template ;
85+ $ csv [$ line ][] = $ filename ;
86+ }
87+
88+ $ this ->document ->removeChild ($ this ->document ->firstChild );
89+
90+ $ filename = substr_replace ($ filename , 'csv ' , strpos ($ filename , $ ext ));
91+ $ handle = fopen ($ filename , 'w ' );
92+
93+ if (!$ handle ) {
94+ return false ;
95+ }
96+
97+ foreach ($ csv as $ row ) {
98+ fputcsv ($ handle , $ row );
99+ }
100+
101+ fclose ($ handle );
102+
103+ return true ;
104+ }
105+
106+ /**
107+ * Creates a various amount of AIML files from a .CSV file
108+ *
109+ * @param string $filename Name of the CSV file
110+ * @return bool
111+ */
112+ public function csv2aiml ($ filename )
113+ {
114+ if (!is_readable ($ filename )) {
115+ throw new \InvalidArgumentException ('File was not found or is not readable ' );
116+ }
117+
118+ if (pathinfo ($ filename , PATHINFO_EXTENSION ) !== 'csv ' ||
119+ !in_array (mime_content_type ($ filename ), ['text/plain ' , 'text/csv ' ])
120+ ) {
121+ throw new \InvalidArgumentException ('Wrong MIME content type or file extension ' );
122+ }
123+
124+ $ handle = fopen ($ filename , 'r ' );
125+
126+ if (!$ handle ) {
127+ return false ;
128+ }
129+
130+ /** @var \DOMElement[] $files */
131+ $ files = [];
132+
133+ while (($ row = fgetcsv ($ handle )) !== false )
134+ {
135+ if (count ($ row ) !== 6 ) {
136+ continue ;
137+ }
138+
139+ if (!isset ($ files [$ row [5 ]]))
140+ {
141+ $ files [$ row [5 ]] = $ this ->document ->createElement ('aiml ' );
142+ $ files [$ row [5 ]]->setAttribute ('version ' , '2.0 ' );
143+ }
144+
145+ foreach ($ row as &$ entity )
146+ {
147+ $ entity = htmlentities (trim ($ entity ));
148+ }
149+
150+ $ category = $ this ->document ->createElement ('category ' );
151+
152+ $ category ->appendChild ($ this ->document ->createElement ('pattern ' , $ row [1 ]));
153+
154+ if ('* ' !== $ row [2 ]) {
155+ $ category ->appendChild ($ this ->document ->createElement ('that ' , $ row [2 ]));
156+ }
157+
158+ if ('* ' !== $ row [3 ]) {
159+ $ category ->appendChild ($ this ->document ->createElement ('topic ' , $ row [3 ]));
160+ }
161+
162+ $ category ->appendChild ($ this ->document ->createElement ('template ' , $ row [4 ]));
163+
164+ $ files [$ row [5 ]]->appendChild ($ category );
165+ }
166+
167+ fclose ($ handle );
168+
169+ foreach ($ files as $ filename => $ aiml )
170+ {
171+ $ this ->document ->appendChild ($ aiml );
172+
173+ $ data = $ this ->document ->saveXML ();
174+ $ data = html_entity_decode ($ data );
175+ $ data = str_replace (['#Comma ' , '#Newline ' ], [', ' , PHP_EOL ], $ data );
176+
177+ file_put_contents ($ filename , $ data );
178+
179+ $ this ->document ->removeChild ($ aiml );
180+ }
181+
182+ return true ;
183+ }
184+ }
0 commit comments