PropertyResources::export()   A
last analyzed

Complexity

Conditions 4
Paths 6

Size

Total Lines 57
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 21
nc 6
nop 0
dl 0
loc 57
rs 9.0309
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * AppserverIo\Resources\Interfaces\Resources
5
 *
6
 * NOTICE OF LICENSE
7
 *
8
 * This source file is subject to the Open Software License (OSL 3.0)
9
 * that is available through the world-wide-web at this URL:
10
 * http://opensource.org/licenses/osl-3.0.php
11
 *
12
 * PHP version 5
13
 *
14
 * @author    Tim Wagner <[email protected]>
15
 * @copyright 2018 TechDivision GmbH <[email protected]>
16
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
 * @link      https://github.com/appserver-io/resources
18
 * @link      http://www.appserver.io
19
 */
20
21
namespace AppserverIo\Resources;
22
23
use AppserverIo\Lang\String;
24
use AppserverIo\Collections\ArrayList;
25
use PhpOffice\PhpSpreadsheet\Spreadsheet;
26
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
27
use AppserverIo\Resources\Exceptions\ResourcesException;
28
use AppserverIo\Resources\Exceptions\ResourcesKeyException;
29
30
/**
31
 * This class bundles several resource files to a so called resource bundle.
32
 *
33
 * It also provides several functions to handle resource files, like an import/export functionality.
34
 *
35
 * @author    Tim Wagner <[email protected]>
36
 * @copyright 2018 TechDivision GmbH <[email protected]>
37
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
38
 * @link      https://github.com/appserver-io/resources
39
 * @link      http://www.appserver.io
40
 */
41
class PropertyResources extends AbstractResources
42
{
43
44
    /**
45
     * Holds the data directory with the path to the resource files to export.
46
     *
47
     * @var \AppserverIo\Lang\String
48
     */
49
    protected $config = null;
50
51
    /**
52
     * Create and return a new resources instance with the specified logical name, after calling its init() method and
53
     * delegating the relevant properties. Concrete subclasses MUST implement this method.
54
     *
55
     * @param \AppserverIo\Lang\String $name   Holds the logical name of the resources to create
56
     * @param \AppserverIo\Lang\String $config Holds the optional string to the configuration
57
     *
58
     * @return void
59
     */
60
    public function __construct(String $name, String $config = null)
61
    {
62
63
        // initialize the superclass
64
        parent::__construct($name);
65
66
        // initialize the members with the passed values
67
        $this->config = $config;
0 ignored issues
show
Documentation Bug introduced by
It seems like $config can also be of type string. However, the property $config is declared as type AppserverIo\Lang\String. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
68
    }
69
70
    /**
71
     * This method searches in the container for the resource with the key passed as parameter.
72
     *
73
     * @param string                              $name         Holds the key of the requested resource
74
     * @param \AppserverIo\Resources\SystemLocale $systemLocale Holds the SystemLocale with which to localize retrieval, or null for the default SystemLocale
75
     * @param \AppserverIo\Collections\ArrayList  $parameter    Holds an ArrayList with parameters with replacements for the placeholders in the resource string
76
     *
77
     * @return string Holds the requested resource value
78
     * @throws \AppserverIo\Resources\Exceptions\ResourcesException Is thrown if an error occurs retrieving or returning the requested content
79
     * @throws \AppserverIo\Resources\Exceptions\ResourcesKeyException Is thrown if the no value for the specified key was found, and isReturnNull() returns false
80
     * @see \AppserverIo\Resources\Interfaces\ResourcesInterface::find()
81
     */
82
    public function find($name, SystemLocale $systemLocale = null, ArrayList $parameter = null)
83
    {
84
85
        // if no Locale is passed, use the property resources default one
86
        if ($systemLocale == null) {
87
            $systemLocale = $this->getDefaultSystemLocale();
88
        }
89
90
        // check if the property resources bundle has already been loaded
91
        if (!$this->exists($systemLocale)) {
92
            $this->add(PropertyResourceBundle::getBundle($this->config, $systemLocale));
93
        }
94
95
        // return the requested resource value
96
        $value = $this->get($systemLocale)->find($name, $parameter);
97
98
        // check if an exception should be thrown if the requested value is null
99
        if (($value == null) && ($this->isReturnNull() == false)) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
100
            throw new ResourcesKeyException('Found no value for requested resource ' . $name);
101
        }
102
103
        // return the requested value
104
        return $value;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $value returns the type string which is incompatible with the documented return type AppserverIo\Lang\String.
Loading history...
105
    }
106
107
    /**
108
     * Initializes the resource bundles for all installed locales.
109
     *
110
     * @return void
111
     */
112
    protected function read()
113
    {
114
115
        // get all installed locales
116
        $locales = SystemLocale::getAvailableLocles();
0 ignored issues
show
Bug introduced by
The method getAvailableLocles() does not exist on AppserverIo\Resources\SystemLocale. Did you maybe mean getAvailableLocales()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

116
        /** @scrutinizer ignore-call */ 
117
        $locales = SystemLocale::getAvailableLocles();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
117
118
        // load the default system locale
119
        $systemLocale = $this->getDefaultSystemLocale();
120
121
        // iterate over the installed locales and instanciate the resource bundles therefore
122
        for ($i = 0; $i < $locales->size(); $i ++) {
123
            $this->add(PropertyResourceBundle::getBundle($this->config, $systemLocale));
124
        }
125
    }
126
127
    /**
128
     * This method creates an Excelsheet and adds for each locale a column
129
     * with the values for it's key.
130
     *
131
     * After adding all resource strings it sends a header with the download
132
     * information of the generated Excelsheet.
133
     *
134
     * @return void
135
     */
136
    public function export()
137
    {
138
139
        // read and initialize the resource files
140
        $this->read();
141
142
        // get the default bundle
143
        $defaultBundle = $this->bundles->get(AbstractResources::getDefaultSystemLocale()->__toString());
0 ignored issues
show
Bug Best Practice introduced by
The method AppserverIo\Resources\Ab...etDefaultSystemLocale() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

143
        $defaultBundle = $this->bundles->get(AbstractResources::/** @scrutinizer ignore-call */ getDefaultSystemLocale()->__toString());
Loading history...
144
145
        // creating a workbook
146
        $spreadsheet = new Spreadsheet();
147
148
        // load the active worksheet
149
        $worksheet = $spreadsheet->getActiveSheet();
150
        $worksheet->setCellValueByColumnAndRow(0, 0, "keys");
151
152
        // get the locale keys from the default resource bundle
153
        $line = 1;
154
155
        // initialize the array for the keys
156
        $keys = array();
157
158
        // write the keys to the worksheet
159
        foreach ($defaultBundle as $key => $value) {
160
            // add the keys to the key array
161
            $keys[] = $key;
162
163
            // write the keys
164
            $worksheet->setCellValueByColumnAndRow($line++, 0, $key);
165
        }
166
167
        // initialize the column counter
168
        $column = 1;
169
170
        // iterate over the resource bundles and add the values
171
        foreach ($this->bundles as $systemLocale => $resources) {
172
            // write the columen with the localee
173
            $worksheet->setCellValueByColumnAndRow(0, $column, $systemLocale);
174
175
            // initialize the counter for the number of lines
176
            $line = 1;
177
178
            // iterate over the the keys and add the values from the resource bundle
179
            foreach ($keys as $key) {
180
                // get the value for the key
181
                $value = $resources->find($key);
182
183
                // the actual data
184
                $worksheet->setCellValueByColumnAndRow($line, $column, $value);
185
                $line ++;
186
            }
187
            $column ++;
188
        }
189
190
        // finally save the file
191
        $writer = new Xlsx($spreadsheet);
0 ignored issues
show
Unused Code introduced by
The call to PhpOffice\PhpSpreadsheet...der\Xlsx::__construct() has too many arguments starting with $spreadsheet. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

191
        $writer = /** @scrutinizer ignore-call */ new Xlsx($spreadsheet);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
192
        $writer->save($this->dataDir . DIRECTORY_SEPARATOR . $defaultBundle->getName()->__toString() . ".xlsx");
0 ignored issues
show
Bug Best Practice introduced by
The property dataDir does not exist on AppserverIo\Resources\PropertyResources. Did you maybe forget to declare it?
Loading history...
Bug introduced by
The method save() does not exist on PhpOffice\PhpSpreadsheet\Reader\Xlsx. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

192
        $writer->/** @scrutinizer ignore-call */ 
193
                 save($this->dataDir . DIRECTORY_SEPARATOR . $defaultBundle->getName()->__toString() . ".xlsx");

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
193
    }
194
195
    /**
196
     * This method imports the resource string from the file with the name specified as parameter.
197
     *
198
     * @param string $fileToImport Holds the name of the file to import the resource strings from
199
     *
200
     * @return void
201
     */
202
    public function import($fileToImport)
203
    {
204
205
        // read and initialize the resource files
206
        $this->read();
207
208
        // initialize the array with the locales
209
        $systemLocales = array();
210
211
        // open the file to import the resource strings from
212
        $handle = @fopen($fileToImport, "r");
213
214
        // throw an exception if the file with the resources to import can't be opened
215
        if (!$handle) {
0 ignored issues
show
introduced by
$handle is of type resource|false, thus it always evaluated to false.
Loading history...
216
            throw new ResourcesException('Can\'t open ' . $fileToImport . ' with resources to import');
217
        }
218
219
        // initialize the counter for the number of lines
220
        $lines = 0;
221
222
        // separate the content in lines
223
        while ($row = fgetcsv($handle, 4096)) {
224
            $key = "";
225
            for ($i = 0; $i <= $this->bundles->size(); $i ++) {
226
                if ($i == 0) {
227
                    $key = $row[$i];
228
                } elseif ($lines == 0 && $i > 0) {
229
                    $systemLocales[$i] = $row[$i];
230
                } else {
231
                    $resources = $this->bundles->get($systemLocales[$i]);
232
                    $resources->replace($key, $row[$i]);
233
                }
234
            }
235
            $lines ++;
236
        }
237
    }
238
}
239