Completed
Push — master ( 1857e6...d96bec )
by Joao
03:02
created

src/Database/SQLHelper.php (8 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
3
namespace ByJG\AnyDataset\Database;
4
5
use ByJG\AnyDataset\Enum\Relation;
6
use ByJG\AnyDataset\Enum\SQLFieldType;
7
use ByJG\AnyDataset\Enum\SQLType;
8
use ByJG\AnyDataset\Repository\DBDataset;
9
use ByJG\AnyDataset\Repository\SingleRow;
10
use DateTime;
11
use Exception;
12
13
class SQLHelper
14
{
15
16
    /**
17
     * @var DBDataset
18
     */
19
    protected $_db;
20
    protected $_fieldDeliLeft = " ";
21
    protected $_fieldDeliRight = " ";
22
23
    /**
24
     *
25
     * @param DBDataset $db
26
     */
27
    public function __construct(DBDataset $db)
28
    {
29
        $this->_db = $db;
30
    }
31
32
    /**
33
     * Generate and Execute UPDATE and INSERTS
34
     *
35
     * @param DBDataset $db
0 ignored issues
show
There is no parameter named $db. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
36
     * @param string $table
37
     * @param array $fields
38
     * @param SQLType $type
39
     * @param string $filter
40
     * @return string
41
     */
42
    public function generateSQL($table, $fields, &$param, $type = SQLType::SQL_INSERT, $filter = "", $decimalpoint = ".")
43
    {
44
        if ($fields instanceof SingleRow) {
45
            return $this->generateSQL($table, $fields->toArray(), $param, $type, $filter, $decimalpoint);
46
        }
47
48
        if ((is_null($param)) || (!is_array($param))) {
49
            $param = array();
50
        }
51
52
        if ($type == SQLType::SQL_UPDATE) {
53
            $sql = "";
54
            foreach ($fields as $fieldname => $fieldvalue) {
55
                if ($sql != "") {
56
                    $sql .= ", ";
57
                }
58
                $sql .= " " . $this->_fieldDeliLeft . $fieldname . $this->_fieldDeliRight . " = " . $this->getValue($fieldname,
59
                        $fieldvalue, $param, $decimalpoint) . " ";
60
            }
61
            $sql = "update $table set $sql where $filter ";
62
        } elseif ($type == SQLType::SQL_INSERT) {
63
            $sql = "";
0 ignored issues
show
$sql is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
64
            $campos = "";
65
            $valores = "";
66
            foreach ($fields as $fieldname => $fieldvalue) {
67
                if ($campos != "") {
68
                    $campos .= ", ";
69
                    $valores .= ", ";
70
                }
71
                $campos .= $this->_fieldDeliLeft . $fieldname . $this->_fieldDeliRight;
72
                $valores .= $this->getValue($fieldname, $fieldvalue, $param, $decimalpoint);
73
            }
74
            $sql = "insert into $table ($campos) values ($valores)";
75
        } elseif ($type == SQLType::SQL_DELETE) {
76
            if ($filter == "") {
77
                throw new Exception("I can't generate delete statements without filter");
78
            }
79
            $sql = "delete from $table where $filter";
80
        }
81
        return $sql;
82
    }
83
84
    /**
85
     * Generic Function
86
     *
87
     * @param unknown_type $valores
88
     * @return unknown
89
     */
90
    protected function getValue($name, $valores, &$param, $decimalpoint)
91
    {
92
        $paramName = "[[" . $name . "]]";
93
        if (!is_array($valores)) {
94
            $valores = array(SQLFieldType::TEXT, $valores);
95
        }
96
97
        if ($valores[0] == SQLFieldType::BOOLEAN) {
98
            if ($valores[1] == "1") {
99
                $param[$name] = 'S';
100
            } else {
101
                $param[$name] = 'N';
102
            }
103
            return $paramName;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $paramName; (string) is incompatible with the return type documented by ByJG\AnyDataset\Database\SQLHelper::getValue of type ByJG\AnyDataset\Database\unknown.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
104
        } elseif (strlen($valores[1]) == 0) { // Zero is Empty!?!?!?!?
105
            return "null";
0 ignored issues
show
Bug Best Practice introduced by
The return type of return 'null'; (string) is incompatible with the return type documented by ByJG\AnyDataset\Database\SQLHelper::getValue of type ByJG\AnyDataset\Database\unknown.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
106
        } elseif ($valores[0] == SQLFieldType::TEXT) {
107
            $param[$name] = trim($valores[1]);
108
            return $paramName;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $paramName; (string) is incompatible with the return type documented by ByJG\AnyDataset\Database\SQLHelper::getValue of type ByJG\AnyDataset\Database\unknown.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
109
        } elseif ($valores[0] == SQLFieldType::DATE) {
110
            $date = ($valores[1] instanceof DateTime ? $valores[1]->format(DBBaseFunctions::YMDH) : $valores[1]);
111
            $param[$name] = $date;
112
            if (($this->_db->getDbType() == 'oci8') || ( ($this->_db->getDbType() == 'dsn') && (strpos($this->_db->getDbConnectionString(),
113
                    "oci8")))) {
114
                return "TO_DATE($paramName, 'YYYY-MM-DD')";
115
            } else {
116
                return $paramName;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $paramName; (string) is incompatible with the return type documented by ByJG\AnyDataset\Database\SQLHelper::getValue of type ByJG\AnyDataset\Database\unknown.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
117
            }
118
        } elseif ($valores[0] == SQLFieldType::NUMBER) {
119
            $search = ($decimalpoint == ".") ? "," : ".";
120
            $valores[1] = trim(str_replace($search, $decimalpoint, $valores[1]));
121
            $param[$name] = $valores[1];
122
            return $paramName;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $paramName; (string) is incompatible with the return type documented by ByJG\AnyDataset\Database\SQLHelper::getValue of type ByJG\AnyDataset\Database\unknown.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
123
        } else {
124
            return $valores[1];
125
        }
126
    }
127
128
    /**
129
     * Used to create a FILTER in a SQL string.
130
     *
131
     * @param string $fieldName
132
     * @param Relation $relation
133
     * @param array() $value
134
     * @param &string $sql (Full SQL)
135
     * @param &string $param
136
     */
137
    public function getWhereClause($fieldName, $relation, $value, &$sql, &$param)
138
    {
139
        if (strlen($sql) > 4) {
140
            $sql .= ' and ';
141
        }
142
        $sql = " $fieldName " . $relation . " " . $this->getValue($fieldName, $value, $param, $decimalpoint);
0 ignored issues
show
The variable $decimalpoint does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
143
    }
144
145
    public function setFieldDelimeters($left, $right)
146
    {
147
        $this->_fieldDeliLeft = $left;
148
        $this->_fieldDeliRight = $right;
149
    }
150
151
    public static function createSafeSQL($sql, $list)
152
    {
153
        foreach ($list as $key => $value) {
154
            $value = str_replace(["'", ';'], ["", ''], $value);
155
            $sql = str_replace($key, $value, $sql);
156
        }
157
        return $sql;
158
    }
159
}
160