1<?php
2
3/**
4 * Class ilBiblFileReaderBase
5 *
6 * @author Fabian Schmid <fs@studer-raimann.ch>
7 */
8abstract class ilBiblFileReaderBase implements ilBiblFileReaderInterface
9{
10
11    /**
12     * Number of maximum allowed characters for attributes in order to fit in the database
13     *
14     * @var int
15     */
16    const ATTRIBUTE_VALUE_MAXIMAL_TEXT_LENGTH = 4000;
17    const ENCODING_UTF_8 = 'UTF-8';
18    const ENCODING_ASCII = 'ASCII';
19    const ENCODING_ISO_8859_1 = 'ISO-8859-1';
20    /**
21     * @var string
22     */
23    protected $file_content = '';
24    /**
25     * @var string
26     */
27    protected $path_to_file = '';
28    /**
29     * @var ilBiblEntryFactoryInterface
30     */
31    protected $entry_factory;
32    /**
33     * @var ilBiblFieldFactoryInterface
34     */
35    protected $field_factory;
36    /**
37     * @var ilBiblAttributeFactoryInterface
38     */
39    protected $attribute_factory;
40
41
42    /**
43     * ilBiblFileReaderBase constructor.
44     *
45     * @param ilBiblEntryFactoryInterface $entry_factory
46     */
47    public function __construct(ilBiblEntryFactoryInterface $entry_factory, ilBiblFieldFactoryInterface $field_factory, ilBiblAttributeFactoryInterface $attribute_factory)
48    {
49        $this->entry_factory = $entry_factory;
50        $this->field_factory = $field_factory;
51        $this->attribute_factory = $attribute_factory;
52    }
53
54
55    /**
56     * @param $path_to_file
57     *
58     * @return bool
59     */
60    public function readContent($path_to_file)
61    {
62        global $DIC;
63        /**
64         * @var $filesystem \ILIAS\Filesystem\Filesystems
65         */
66        $filesystem = $DIC["filesystem"];
67        $this->setPathToFile($path_to_file);
68        $this->setFileContent($this->convertStringToUTF8($filesystem->storage()->read($path_to_file)));
69
70        return true;
71    }
72
73
74    /**
75     * @param $string
76     *
77     * @return string
78     */
79    protected function convertStringToUTF8($string)
80    {
81        if (!function_exists('mb_detect_encoding') || !function_exists('mb_detect_order')
82            || !function_exists("mb_convert_encoding")
83        ) {
84            return $string;
85        }
86        ob_end_clean();
87        $mb_detect_encoding = mb_detect_encoding($string);
88        mb_detect_order(array(self::ENCODING_UTF_8, self::ENCODING_ISO_8859_1));
89        switch ($mb_detect_encoding) {
90            case self::ENCODING_UTF_8:
91                break;
92            case self::ENCODING_ASCII:
93                $string = utf8_encode(iconv(self::ENCODING_ASCII, 'UTF-8//IGNORE', $string));
94                break;
95            default:
96                $string = mb_convert_encoding($string, self::ENCODING_UTF_8, $mb_detect_encoding);
97                break;
98        }
99
100        return $string;
101    }
102
103
104    /**
105     * @return string
106     */
107    public function getFileContent()
108    {
109        return $this->file_content;
110    }
111
112
113    /**
114     * @param string $file_content
115     */
116    public function setFileContent($file_content)
117    {
118        $this->file_content = $file_content;
119    }
120
121
122    /**
123     * @return string
124     */
125    public function getPathToFile()
126    {
127        return $this->path_to_file;
128    }
129
130
131    /**
132     * @param string $path_to_file
133     */
134    public function setPathToFile($path_to_file)
135    {
136        $this->path_to_file = $path_to_file;
137    }
138
139
140    /**
141     * @inheritDoc
142     */
143    public function parseContentToEntries(ilObjBibliographic $bib)
144    {
145        $entries_from_file = $this->parseContent();
146        $entry_instances = [];
147        //fill each entry into a ilBibliographicEntry object and then write it to DB by executing doCreate()
148        foreach ($entries_from_file as $file_entry) {
149            $type = null;
150            $x = 0;
151            $parsed_entry = array();
152            foreach ($file_entry as $key => $attribute) {
153                // if the attribute is an array, make a comma separated string out of it
154                if (is_array($attribute)) {
155                    $attribute = implode(", ", $attribute);
156                }
157                // reduce the attribute strings to a maximum of 4000 (ATTRIBUTE_VALUE_MAXIMAL_TEXT_LENGTH) characters, in order to fit in the database
158                //if (mb_strlen($attribute, 'UTF-8') > self::ATTRIBUTE_VALUE_MAXIMAL_TEXT_LENGTH) {
159                if (ilStr::strLen($attribute) > self::ATTRIBUTE_VALUE_MAXIMAL_TEXT_LENGTH) {
160                    // $attribute = mb_substr($attribute, 0, self::ATTRIBUTE_VALUE_MAXIMAL_TEXT_LENGTH - 3, 'UTF-8') . '...';
161                    $attribute = ilStr::subStr($attribute, 0, self::ATTRIBUTE_VALUE_MAXIMAL_TEXT_LENGTH - 3) . '...';
162                }
163                // ty (RIS) or entryType (BIB) is the type and is treated seperately
164                if (strtolower($key) == 'ty' || strtolower($key) == 'entrytype') {
165                    $type = $attribute;
166                    continue;
167                }
168                //TODO - Refactoring for ILIAS 4.5 - get rid off array restructuring
169                //change array structure (name not as the key, but under the key "name")
170                $parsed_entry[$x]['name'] = $key;
171                $parsed_entry[$x]['value'] = $attribute;
172                $x++;
173            }
174            /**
175             * @var $entry_model ilBiblEntry
176             */
177            //create the entry and fill data into database by executing doCreate()
178            $entry_factory = $this->getEntryFactory();
179            $entry_model = $entry_factory->getEmptyInstance();
180            $entry_model->setType($type);
181            $entry_model->setDataId($bib->getId());
182            $entry_model->store();
183            foreach ($parsed_entry as $entry) {
184                $this->getAttributeFactory()->createAttribute($entry['name'], $entry['value'], $entry_model->getId());
185            }
186            //$entry_model->doCreate();
187            $entry_instances[] = $entry_model;
188        }
189
190        return $entry_instances;
191    }
192
193
194    /**
195     * @inheritdoc
196     */
197    public function getEntryFactory()
198    {
199        return $this->entry_factory;
200    }
201
202
203    /**
204     * @inheritdoc
205     */
206    public function getFieldFactory()
207    {
208        return $this->field_factory;
209    }
210
211
212    /**
213     * @inheritDoc
214     */
215    public function getAttributeFactory()
216    {
217        return $this->attribute_factory;
218    }
219}
220