Completed
Push — master ( 32ca2f...3d4ee7 )
by Andreas
16:33
created

net_nemein_wiki_handler_create   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 140
Duplicated Lines 0 %

Test Coverage

Coverage 74.65%

Importance

Changes 0
Metric Value
eloc 75
c 0
b 0
f 0
dl 0
loc 140
ccs 53
cts 71
cp 0.7465
rs 10
wmc 16

3 Methods

Rating   Name   Duplication   Size   Complexity  
A save_callback() 0 8 1
B check_unique_wikiword() 0 60 9
B _handler_create() 0 44 6
1
<?php
2
/**
3
 * @package net.nemein.wiki
4
 * @author The Midgard Project, http://www.midgard-project.org
5
 * @copyright The Midgard Project, http://www.midgard-project.org
6
 * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License
7
 */
8
9
use midcom\datamanager\schemadb;
10
use midcom\datamanager\datamanager;
11
use midcom\datamanager\controller;
12
use Symfony\Component\HttpFoundation\Request;
13
14
/**
15
 * Wikipage creation handler
16
 *
17
 * @package net.nemein.wiki
18
 */
19
class net_nemein_wiki_handler_create extends midcom_baseclasses_components_handler
20
{
21
    use net_nemein_wiki_handler;
0 ignored issues
show
Bug introduced by
The trait net_nemein_wiki_handler requires the property $id which is not provided by net_nemein_wiki_handler_create.
Loading history...
22
23
    /**
24
     * Wiki word we're creating page for
25
     *
26
     * @var string
27
     */
28
    private $_wikiword = '';
29
30
    /**
31
     * The wikipage we're creating
32
     *
33
     * @var net_nemein_wiki_wikipage
34
     */
35
    private $_page;
36
37 3
    private function check_unique_wikiword($wikiword, $schema)
38
    {
39 3
        $resolver = new net_nemein_wiki_resolver($this->_topic->id);
40 3
        $resolved = $resolver->path_to_wikipage($wikiword, true, true);
41
42 3
        if (!empty($resolved['latest_parent'])) {
43 1
            $to_node = $resolved['latest_parent'];
44
        } else {
45 3
            $to_node = $resolved['folder'];
46
        }
47 3
        if (strstr($resolved['remaining_path'], '/')) {
48
            // One or more namespaces left, find first, create it and recurse
49 1
            $paths = explode('/', $resolved['remaining_path']);
50 1
            $folder_title = array_shift($paths);
51 1
            $topic = new midcom_db_topic();
52 1
            $topic->up = $to_node[MIDCOM_NAV_ID];
53 1
            $topic->extra = trim($folder_title);
54 1
            $topic->title = $topic->extra;
55 1
            $topic->name = midcom_helper_misc::urlize($folder_title);
56 1
            $topic->component = 'net.nemein.wiki';
57 1
            if (!$topic->create()) {
58
                throw new midcom_error("Could not create wiki namespace '{$folder_title}', last Midgard error was: " . midcom_connection::get_error_string());
59
            }
60
            // refresh
61 1
            $topic = new midcom_db_topic($topic->id);
62
63
            // See if we have article with same title in immediate parent
64 1
            $qb = net_nemein_wiki_wikipage::new_query_builder();
65 1
            $qb->add_constraint('title', '=', $folder_title);
66 1
            $qb->add_constraint('topic', '=', $topic->up);
67 1
            $results = $qb->execute();
68
69 1
            if (count($results) == 1) {
70
                $article = $results[0];
71
                $article->name = 'index';
0 ignored issues
show
Bug Best Practice introduced by
The property name does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
72
                $article->topic = $topic->id;
0 ignored issues
show
Bug Best Practice introduced by
The property topic does not exist on midcom_core_dbaobject. Since you implemented __set, consider adding a @property annotation.
Loading history...
73
                if (!$article->update()) {
74
                    // Could not move article, do something ?
75
                }
76
            } else {
77
                try {
78 1
                    $this->initialize_index_article($topic);
79
                } catch (midcom_error $e) {
80
                    // Could not create index
81
                    $topic->delete();
82
                    throw $e;
83
                }
84
            }
85
            // We have created a new topic, now recurse to create the rest of the path.
86 1
            return $this->check_unique_wikiword($wikiword, $schema);
87
        }
88 3
        if (is_object($resolved['wikipage'])) {
89
            // Page exists
90
            throw new midcom_error('Wiki page with that name already exists.');
91
        }
92
        // No more namespaces left, create the page to latest parent
93 3
        if ($to_node[MIDCOM_NAV_ID] != $this->_topic->id) {
94
            // Last parent is not this topic, redirect there
95 1
            $wikiword_url = rawurlencode($resolved['remaining_path']);
96 1
            return new midcom_response_relocate($to_node[MIDCOM_NAV_ABSOLUTEURL] . "create/{$schema}/?wikiword={$wikiword_url}");
97
        }
98 2
    }
99
100
    /**
101
     * @param Request $request The request object
102
     * @param array $data The local request data.
103
     * @param string $schema The DM schema
104
     */
105 3
    public function _handler_create(Request $request, array &$data, $schema = null)
106
    {
107
        // Initialize sessioning first
108 3
        $data['session'] = new midcom_services_session();
109
110 3
        if (!$request->query->has('wikiword')) {
111
            if (!$data['session']->exists('wikiword')) {
112
                throw new midcom_error_notfound('No wiki word given');
113
            }
114
            $this->_wikiword = $data['session']->get('wikiword');
115
        } else {
116 3
            $this->_wikiword = $request->query->get('wikiword');
117 3
            $data['session']->set('wikiword', $this->_wikiword);
118
        }
119
120 3
        $this->_topic->require_do('midgard:create');
121
122 3
        $schema = $schema ?: $this->_config->get('default_schema');
123
124 3
        $schemadb = schemadb::from_path($this->_config->get('schemadb'));
125 3
        if (!$schemadb->has($schema)) {
126
            throw new midcom_error_notfound('Schema ' . $schema . ' not found in schemadb');
0 ignored issues
show
Bug introduced by
Are you sure $schema of type false|mixed|string can be used in concatenation? ( Ignorable by Annotation )

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

126
            throw new midcom_error_notfound('Schema ' . /** @scrutinizer ignore-type */ $schema . ' not found in schemadb');
Loading history...
127
        }
128 3
        if ($response = $this->check_unique_wikiword($this->_wikiword, $schema)) {
129 1
            return $response;
130
        }
131
132 2
        $this->_page = new net_nemein_wiki_wikipage();
133 2
        $this->_page->topic = $this->_topic->id;
134 2
        $this->_page->title = $this->_wikiword;
135 2
        $this->_page->author = midcom_connection::get_user();
0 ignored issues
show
Bug Best Practice introduced by
The property author does not exist on net_nemein_wiki_wikipage. Since you implemented __set, consider adding a @property annotation.
Loading history...
136
137 2
        $dm = new datamanager($schemadb);
138 2
        $data['controller'] = $dm
139 2
            ->set_storage($this->_page)
140 2
            ->get_controller();
141
142 2
        midcom::get()->head->set_pagetitle(sprintf($this->_l10n->get('create wikipage %s'), $this->_wikiword));
143
144 2
        $workflow = $this->get_workflow('datamanager', [
145 2
            'controller' => $data['controller'],
146 2
            'save_callback' => [$this, 'save_callback']
147
        ]);
148 2
        return $workflow->run($request);
149
    }
150
151
    public function save_callback(controller $controller)
152
    {
153
        $indexer = midcom::get()->indexer;
154
        net_nemein_wiki_viewer::index($controller->get_datamanager(), $indexer, $this->_topic);
155
156
        midcom::get()->uimessages->add($this->_l10n->get('net.nemein.wiki'), sprintf($this->_l10n->get('page %s added'), $this->_wikiword));
157
158
        return "{$this->_page->name}/";
159
    }
160
}
161