GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( fd5a04...21cd55 )
by Nico
29:44
created

MakeEln::getAuthorId()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 3.004

Importance

Changes 0
Metric Value
cc 3
eloc 11
nc 4
nop 4
dl 0
loc 19
ccs 12
cts 13
cp 0.9231
crap 3.004
rs 9.9
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
/**
3
 * @author Nicolas CARPi <[email protected]>
4
 * @copyright 2022 Nicolas CARPi
5
 * @see https://www.elabftw.net Official website
6
 * @license AGPL-3.0
7
 * @package elabftw
8
 */
9
10
namespace Elabftw\Make;
11
12
use DateTimeImmutable;
13
use Elabftw\Exceptions\IllegalActionException;
14
use Elabftw\Models\AbstractEntity;
15
use Elabftw\Models\Config;
16
use League\Flysystem\UnableToReadFile;
0 ignored issues
show
Bug introduced by
The type League\Flysystem\UnableToReadFile was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use ZipStream\ZipStream;
0 ignored issues
show
Bug introduced by
The type ZipStream\ZipStream was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
18
19
/**
20
 * Make an ELN archive
21
 */
22
class MakeEln extends MakeStreamZip
23
{
24
    private const HASH_ALGO = 'sha256';
25
26
    protected string $extension = '.eln';
27
28
    private array $authors = array();
29
30
    // name of the folder containing everything
31
    private string $root;
32
33 6
    public function __construct(protected ZipStream $Zip, AbstractEntity $entity, protected array $idArr)
34
    {
35 6
        parent::__construct($Zip, $entity, $idArr);
36 6
        $now = new DateTimeImmutable();
37 6
        $this->root = $now->format('Y-m-d-His') . '-export';
38 6
        $this->jsonArr = array(
39 6
            '@context' => 'https://w3id.org/ro/crate/1.1/context',
40 6
            '@graph' => array(
41 6
                array(
42 6
                    '@id' => 'ro-crate-metadata.json',
43 6
                    '@type' => 'CreativeWork',
44 6
                    'about' => array('@id' => './'),
45 6
                    'conformsTo' => array('@id' => 'https://w3id.org/ro/crate/1.1'),
46 6
                    'dateCreated' => $now->format(DateTimeImmutable::ATOM),
47 6
                    'sdPublisher' => array(
48 6
                        '@type' => 'Organization',
49 6
                        'name' => 'eLabFTW',
50 6
                        'logo' => 'https://www.elabftw.net/img/elabftw-logo-only.svg',
51 6
                        'slogan' => 'A free and open source electronic lab notebook.',
52 6
                        'url' => 'https://www.elabftw.net',
53 6
                        'parentOrganization' => array(
54 6
                          '@type' => 'Organization',
55 6
                          'name' => 'Deltablot',
56 6
                          'logo' => 'https://www.deltablot.com/img/logos/deltablot.svg',
57 6
                          'slogan' => 'Open Source software for research labs.',
58 6
                          'url' => 'https://www.deltablot.com',
59 6
                        ),
60 6
                    ),
61 6
                    'version' => '1.0',
62 6
                ),
63 6
            ),
64 6
        );
65
    }
66
67 2
    public function getFileName(): string
68
    {
69 2
        return $this->root . $this->extension;
70
    }
71
72
    /**
73
     * Loop on each id and add it to our eln archive
74
     */
75 5
    public function getStreamZip(): void
76
    {
77 5
        $dataEntities = array();
78
        // an array of "@id" for main datasets
79 5
        $rootParts = array();
80 5
        foreach ($this->idArr as $id) {
81 5
            $hasPart = array();
82
            try {
83 5
                $this->Entity->setId((int) $id);
84
            } catch (IllegalActionException $e) {
85
                continue;
86
            }
87 5
            $e = $this->Entity->entityData;
88 5
            $currentDatasetFolder = $this->getBaseFileName();
89 5
            $this->folder = $this->root . '/' . $currentDatasetFolder;
90 5
            $rootParts[] = array('@id' => './' . $currentDatasetFolder);
91
92
            // LINKS
93 5
            $mentions = array();
94 5
            foreach ($e['items_links'] as $link) {
95 3
                $mentions[] = array(
96 3
                    '@id' => Config::fromEnv('SITE_URL') . '/database.php?mode=view&id=' . $link['itemid'],
97 3
                    '@type' => 'Dataset',
98 3
                    'name' => $link['category'] . ' - ' . $link['title'],
99 3
                    'identifier' => $link['elabid'],
100 3
                );
101
            }
102 5
            foreach ($e['experiments_links'] as $link) {
103
                $mentions[] = array(
104
                    '@id' => Config::fromEnv('SITE_URL') . '/experiments.php?mode=view&id=' . $link['itemid'],
105
                    '@type' => 'Dataset',
106
                    'name' => $link['category'] . ' - ' . $link['title'],
107
                    'identifier' => $link['elabid'],
108
                );
109
            }
110
111
            // JSON
112 5
            $MakeJson = new MakeJson($this->Entity, array((int) $e['id']));
113 5
            $json = $MakeJson->getFileContent();
114 5
            $this->Zip->addFile($this->folder . '/' . $MakeJson->getFileName(), $json);
115 5
            $jsonAtId = './' . $currentDatasetFolder . '/' . $MakeJson->getFileName();
116
            // add the json in the hasPart of the entry
117 5
            $hasPart[] = array('@id' => $jsonAtId);
118 5
            $dataEntities[] = array(
119 5
                '@id' => $jsonAtId,
120 5
                '@type' => 'File',
121 5
                'description' => 'JSON export',
122 5
                'name' => $MakeJson->getFileName(),
123 5
                'encodingFormat' => $MakeJson->getContentType(),
124 5
                'contentSize' => (string) $MakeJson->getContentSize(),
125 5
                'sha256' => hash('sha256', $json),
126 5
            );
127
128
            // COMMENTS
129 5
            $comments = array();
130 5
            foreach ($e['comments'] as $comment) {
131
                $firstname = $comment['firstname'] ?? '';
132
                $lastname = $comment['lastname'] ?? '';
133
                $dateCreated = (new DateTimeImmutable($e['created_at']))->format(DateTimeImmutable::ATOM);
134
                $comments[] = array(
135
                    '@id' => 'comment://' . urlencode($dateCreated),
136
                    'dateCreated' => $dateCreated,
137
                    'text' => $comment['comment'],
138
                    'author' => array('@id' => $this->getAuthorId($comment['userid'], $firstname, $lastname, $comment['orcid'])),
139
                );
140
            }
141
142
            // UPLOADS
143 5
            $uploadedFilesArr = $e['uploads'];
144 5
            if (!empty($uploadedFilesArr)) {
145
                try {
146
                    // this gets modified by the function so we have the correct real_names
147 4
                    $uploadedFilesArr = $this->addAttachedFiles($uploadedFilesArr);
148
                } catch (UnableToReadFile $e) {
149
                    continue;
150
                }
151 4
                foreach ($uploadedFilesArr as $file) {
152 4
                    $uploadAtId = './' . $currentDatasetFolder . '/' . $file['real_name'];
153 4
                    $hasPart[] = array('@id' => $uploadAtId);
154 4
                    $dataEntities[] = array(
155 4
                        '@id' => $uploadAtId,
156 4
                        '@type' => 'File',
157 4
                        'description' => $file['comment'] ?? '',
158 4
                        'name' => $file['real_name'],
159 4
                        'alternateName' => $file['long_name'],
160 4
                        'contentSize' => $file['filesize'],
161 4
                        'sha256' => $file['hash'] ?? hash_file('sha256', $uploadAtId),
162 4
                    );
163
                }
164
            }
165
166
            // TAGS
167 5
            $keywords = array();
168 5
            if ($this->Entity->entityData['tags']) {
169 5
                $keywords = explode('|', (string) $this->Entity->entityData['tags']);
170
            }
171
172
            // MAIN ENTRY
173 5
            $firstname = $e['firstname'] ?? '';
174 5
            $lastname = $e['lastname'] ?? '';
175 5
            $dataEntities[] = array(
176 5
                '@id' => './' . $currentDatasetFolder,
177 5
                '@type' => 'Dataset',
178 5
                'author' => array('@id' => $this->getAuthorId($e['userid'], $firstname, $lastname, $e['orcid'])),
179 5
                'dateCreated' => (new DateTimeImmutable($e['created_at']))->format(DateTimeImmutable::ATOM),
180 5
                'dateModified' => (new DateTimeImmutable($e['modified_at']))->format(DateTimeImmutable::ATOM),
181 5
                'identifier' => $e['elabid'] ?? '',
182 5
                'comment' => $comments,
183 5
                'keywords' => $keywords,
184 5
                'name' => $e['title'],
185 5
                'text' => $e['body'] ?? '',
186 5
                'url' => Config::fromEnv('SITE_URL') . '/' . $this->Entity->page . '.php?mode=view&id=' . $e['id'],
187 5
                'hasPart' => $hasPart,
188 5
                'mentions' => $mentions,
189 5
            );
190
        }
191
        // add the description of root with hasPart property
192 5
        $dataEntities[] = array(
193 5
            '@id' => './',
194 5
            '@type' => array('Dataset'),
195 5
            'hasPart' => $rootParts,
196 5
        );
197
198
        // merge all, including authors
199 5
        $this->jsonArr['@graph'] = array_merge($this->jsonArr['@graph'], $dataEntities, $this->authors);
200
201
        // add the metadata json file containing references to all the content of our crate
202 5
        $this->Zip->addFile($this->root . '/ro-crate-metadata.json', json_encode($this->jsonArr, JSON_THROW_ON_ERROR, 512));
203 5
        $this->Zip->finish();
204
    }
205
206
    /**
207
     * Generate an author node unless it exists already
208
     */
209 5
    private function getAuthorId(int $userid, string $firstname, string $lastname, ?string $orcid): string
210
    {
211
        // add firstname and lastname to the hash to get more entropy. Use the userid too so similar names won't collide.
212 5
        $id = sprintf('person://%s?hash_algo=%s', hash(self::HASH_ALGO, (string) $userid . $firstname . $lastname), self::HASH_ALGO);
213 5
        $node = array(
214 5
            '@id' => $id,
215 5
            '@type' => 'Person',
216 5
            'familyName' => $lastname,
217 5
            'givenName' => $firstname,
218 5
        );
219
        // only add an identifier property if there is an orcid
220 5
        if ($orcid !== null) {
221
            $node['identifier'] = 'https://orcid.org/' . $orcid;
222
        }
223
        // only add it if it doesn't exist yet in our list of authors
224 5
        if (!in_array($id, array_column($this->authors, '@id'), true)) {
225 5
            $this->authors[] = $node;
226
        }
227 5
        return $id;
228
    }
229
}
230