Issues (1131)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

src/database/DoctrineDatabase.class.php (5 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
namespace Agavi\Database;
3
4
// +---------------------------------------------------------------------------+
5
// | This file is part of the Agavi package.                                   |
6
// | Copyright (c) 2005-2011 the Agavi Project.                                |
7
// |                                                                           |
8
// | For the full copyright and license information, please view the LICENSE   |
9
// | file that was distributed with this source code. You can also view the    |
10
// | LICENSE file online at http://www.agavi.org/LICENSE.txt                   |
11
// |   vi: set noexpandtab:                                                    |
12
// |   Local Variables:                                                        |
13
// |   indent-tabs-mode: t                                                     |
14
// |   End:                                                                    |
15
// +---------------------------------------------------------------------------+
16
use Agavi\Exception\DatabaseException;
17
18
/**
19
 * A database adapter for the Doctrine ORM.
20
 *
21
 * @package    agavi
22
 * @subpackage database
23
 *
24
 * @author     Ross Lawley <[email protected]>
25
 * @author     David Zülke <[email protected]>
26
 * @author     TANAKA Koichi <[email protected]>
27
 * @copyright  Authors
28
 * @copyright  The Agavi Project
29
 *
30
 * @since      0.11.0
31
 *
32
 * @version    $Id$
33
 */
34
class DoctrineDatabase extends Database
35
{
36
    /**
37
     * @var        Doctrine_Manager The Doctrine Manager instance we should use.
38
     */
39
    protected $doctrineManager;
40
    
41
    /**
42
     * Connect to the database.
43
     *
44
     * @throws     <b>AgaviDatabaseException</b> If a connection could not be
45
     *                                           created.
46
     *
47
     * @author     David Zülke <[email protected]>
48
     * @since      0.11.0
49
     */
50
    public function connect()
51
    {
52
        // this doesn't do anything, Doctrine is handling the lazy connection stuff
53
    }
54
    
55
    /**
56
     * Retrieve a raw database resource associated with this Database
57
     * implementation.
58
     *
59
     * @return     mixed A database resource.
60
     *
61
     * @throws     <b>AgaviDatabaseException</b> If no resource could be retrieved
62
     *
63
     * @author     David Zülke <[email protected]>
64
     * @since      0.11.0
65
     */
66
    public function getResource()
67
    {
68
        return $this->getConnection()->getDbh();
69
    }
70
71
    /**
72
     * Initialize Doctrine set the autoloading
73
     *
74
     * @param      DatabaseManager $databaseManager The database manager of this instance.
75
     * @param      array           $parameters An assoc array of initialization params.
76
     *
77
     * @author     David Zülke <[email protected]>
78
     * @author     Ross Lawley <[email protected]>
79
     * @author     TANAKA Koichi <[email protected]>
80
     * @since      0.11.0
81
     */
82
    public function initialize(DatabaseManager $databaseManager, array $parameters = array())
83
    {
84
        parent::initialize($databaseManager, $parameters);
85
        
86
        $name = $this->getName();
87
        
88
        // try to autoload doctrine
89
        if (!class_exists('Doctrine')) {
90
            // okay that didn't work. last resort: include it. we assume it's on the include path by default
91
            require('Doctrine.php');
92
        }
93
        
94
        $is12 = version_compare(Doctrine::VERSION, '1.2', '>=');
95
        
96
        if (!$is12) {
97
            trigger_error('Support for Doctrine versions older than 1.2 is deprecated and will be removed in Agavi 1.2.', E_USER_DEPRECATED);
98
        }
99
        
100
        // in any case, it's loaded now. maybe we need to register the autoloading stuff for it!
101
        // we need this list further down
102
        $splAutoloadFunctions = spl_autoload_functions();
103 View Code Duplication
        if (!in_array(array('Doctrine', 'autoload'), $splAutoloadFunctions) && !in_array(array('Doctrine_Core', 'autoload'), $splAutoloadFunctions)) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
104
            // we do
105
            spl_autoload_register(array('Doctrine', 'autoload'));
106
        }
107
        
108
        // cool. Assign the Doctrine Manager instance
109
        $this->doctrineManager = Doctrine_Manager::getInstance();
110
        
111
        // now we're in business. we will set up connections right away, as Doctrine is handling the lazy-connecting stuff for us.
112
        // that way, you can just start using classes in your code
113
        try {
114
            $dsn = $this->getParameter('dsn');
115
            
116
            if ($dsn === null) {
117
                // missing required dsn parameter
118
                $error = 'Database configuration specifies method "dsn", but is missing dsn parameter';
119
                throw new DatabaseException($error);
120
            }
121
            
122
            $this->connection = $this->doctrineManager->openConnection($dsn, $name);
123
            // do not assign the resource here. that would connect to the database
124
            // $this->resource = $this->connection->getDbh();
0 ignored issues
show
Unused Code Comprehensibility introduced by
54% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
125
            
126
            // set our event listener that, on connect, sets the configured charset and runs init queries
127
            $cel = $this->getParameter('connection_event_listener_class', 'AgaviDoctrineDatabaseEventListener');
128
            $this->connection->setListener(new $cel($this));
129
            
130
            // set the context instance as a connection parameter
131
            $this->connection->setParam('context', $databaseManager->getContext(), 'org.agavi');
132
            
133
            // date format
134
            if ($this->hasParameter('date_format')) {
135
                $this->connection->setDateFormat($this->getParameter('date_format'));
136
            }
137
            
138
            // options
139
            foreach ((array)$this->getParameter('options') as $optionName => $optionValue) {
140
                $this->connection->setOption($optionName, $optionValue);
141
            }
142
            
143
            foreach (array(
144
                'manager_attributes' => $this->doctrineManager,
145
                'attributes' => $this->connection,
146
            ) as $attributesKey => $attributesDestination) {
147
                foreach ((array)$this->getParameter($attributesKey, array()) as $attributeName => $attributeValue) {
148
                    if ($is12) {
149
                        if (!strpos($attributeName, '::')) {
150
                            throw new DatabaseException(sprintf('For Doctrine 1.2 and newer, attribute names (and, if desired to be resolved against a constant, values) must be fully qualified, e.g. "Doctrine_Core::ATTR_VALIDATE" and "Doctrine_Core::VALIDATE_NONE". Given attribute with name "%s" in collection "%s" does not match this condition.', $attributeName, $attributesKey));
151
                        }
152
                        if (!defined($attributeName)) {
153
                            throw new DatabaseException(sprintf('Unknown Attribute "%s"', $attributeName));
154
                        }
155
                    }
156
                    
157
                    // resolve from constant if possible
158
                    if (strpos($attributeName, '::') && defined($attributeName)) {
159
                        $attributeName = constant($attributeName);
160
                    }
161
                    
162
                    if (strpos($attributeValue, '::') && defined($attributeValue)) {
163
                        // resolve from constant if possible
164
                        $attributeValue = constant($attributeValue);
165
                    } elseif (ctype_digit($attributeValue)) {
166
                        // cast numeric type to int
167
                        $attributeValue = (int)$attributeValue;
168
                    } elseif (($attributeName == Doctrine::ATTR_QUERY_CACHE || $attributeName == Doctrine::ATTR_RESULT_CACHE) && (is_string($attributeValue) || (is_array($attributeValue) && isset($attributeValue['class'])))) {
169
                        // handle special case for query and result caches, where the attribute value needs to be an instance of Doctrine_Cache_Driver
170
                        // we only allow basic cases where the ctor argument array for options requires scalar values
171
                        // if people want to use e.g. Doctrine_Cache_Db, which requires an instance of Doctrine_Connection as the argument, they should use a custom connection event listener
172
                        $driverClass = is_string($attributeValue) ? $attributeValue : $attributeValue['class'];
173
                        $driverOptions = is_array($attributeValue) && isset($attributeValue['options']) && is_array($attributeValue['options']) ? $attributeValue['options'] : array();
174
                        $attributeValue = new $driverClass($driverOptions);
175
                    }
176
                    
177
                    $attributesDestination->setAttribute($attributeName, $attributeValue);
178
                }
179
            }
180
            
181
            foreach ((array)$this->getParameter('impls', array()) as $templateName => $className) {
182
                $this->connection->setImpl($templateName, $className);
183
            }
184
            
185
            foreach ((array)$this->getParameter('manager_impls', array()) as $templateName => $className) {
186
                $this->doctrineManager->setImpl($templateName, $className);
187
            }
188
            
189
            // load models (that'll just work with empty values too)
190
            Doctrine::loadModels($this->getParameter('load_models'));
191
            
192
            // for 1.2, handle model autoloading and base paths
193
            if ($is12 && ($this->hasParameter('load_models') || $this->hasParameter('models_directory'))) {
194 View Code Duplication
                if (!in_array(array('Doctrine', 'modelsAutoload'), $splAutoloadFunctions) && !in_array(array('Doctrine_Core', 'modelsAutoload'), $splAutoloadFunctions)) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
195
                    spl_autoload_register(array('Doctrine_Core', 'modelsAutoload'));
196
                }
197
                
198
                if ($this->hasParameter('models_directory')) {
199
                    Doctrine_Core::setModelsDirectory($this->getParameter('models_directory'));
200
                }
201
            }
202
            
203
            // for 1.2, handle extension autoloading, base paths and registration
204
            if ($is12 && ($this->hasParameter('extensions_path') || $this->hasParameter('register_extensions'))) {
205 View Code Duplication
                if (!in_array(array('Doctrine', 'extensionsAutoload'), $splAutoloadFunctions) && !in_array(array('Doctrine_Core', 'extensionsAutoload'), $splAutoloadFunctions)) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
206
                    spl_autoload_register(array('Doctrine_Core', 'extensionsAutoload'));
207
                }
208
                
209
                if ($this->hasParameter('extensions_path')) {
210
                    Doctrine_Core::setExtensionsPath($this->getParameter('extensions_path'));
211
                }
212
                foreach ((array)$this->getParameter('register_extensions', array()) as $extensionName) {
213
                    if (is_array($extensionName)) {
214
                        call_user_func_array(array($this->doctrineManager, 'registerExtension'), $extensionName);
215
                    } else {
216
                        $this->doctrineManager->registerExtension($extensionName);
217
                    }
218
                }
219
            }
220
            
221
            foreach ((array)$this->getParameter('bind_components', array()) as $componentName) {
222
                $this->doctrineManager->bindComponent($componentName, $name);
223
            }
224
        } catch (Doctrine_Exception $e) {
0 ignored issues
show
The class Agavi\Database\Doctrine_Exception does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
225
            // the connection's foobar'd
226
            throw new DatabaseException($e->getMessage(), 0, $e);
227
        }
228
    }
229
    
230
    /**
231
     * Execute the shutdown procedure.
232
     *
233
     * @throws     <b>AgaviDatabaseException</b> If an error occurs while shutting
234
     *                                           down this database.
235
     *
236
     * @author     David Zülke <[email protected]>
237
     * @since      0.11.0
238
     */
239
    public function shutdown()
240
    {
241
        if ($this->connection !== null) {
242
            $this->doctrineManager->closeConnection($this->connection);
243
            $this->connection = null;
244
            $this->resource = null;
245
        }
246
    }
247
    
248
    /**
249
     * Get the Doctrine Manager instance.
250
     *
251
     * @return     Doctrine_Manager The Doctrine Manager instance.
252
     *
253
     * @author     David Zülke <[email protected]>
254
     * @since      0.11.0
255
     */
256
    public function getDoctrineManager()
257
    {
258
        return $this->doctrineManager;
259
    }
260
}
261