ASP Classic blog framework - BrainOrdure
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

645 líneas
20KB

  1. <%
  2. Function QuoteValue(val)
  3. if IsWrappedInSingleQuotes(val) then
  4. QuoteValue = val
  5. Exit Function
  6. end if
  7. Select Case VarType(val)
  8. Case vbString
  9. QuoteValue = "'" & Replace(val, "'", "''") & "'"
  10. Case vbDate
  11. if conn.Provider = "Microsoft.Jet.OLEDB.4.0" or conn.Provider = "Microsoft.ACE.OLEDB.12.0" then
  12. QuoteValue = "#" & FormatDateTime(val, 0) & "#"
  13. else
  14. ' SQL Server
  15. QuoteValue = "'" & FormatDateTime(val, 0) & "'"
  16. end if
  17. Case vbNull, vbEmpty
  18. QuoteValue = "Null"
  19. Case vbBoolean
  20. ' Return boolean values without quotes
  21. QuoteValue = "'" & CStr(val) & "'"
  22. Case Else
  23. If IsNumeric(val) Then
  24. QuoteValue = CLng(val)
  25. Else
  26. QuoteValue = CStr(val)
  27. End If
  28. End Select
  29. End Function
  30. Public Function GetAppSetting(key)
  31. Dim cacheKey, xml, nodes, node, i
  32. cacheKey = "AppSetting_" & key
  33. ' Check Application cache first for performance
  34. If Not IsEmpty(Application(cacheKey)) Then
  35. GetAppSetting = Application(cacheKey)
  36. Exit Function
  37. End If
  38. ' Load from web.config only if not cached
  39. Set xml = Server.CreateObject("Microsoft.XMLDOM")
  40. xml.Load(Server.MapPath("web.config"))
  41. Set nodes = xml.selectNodes("//appSettings/add")
  42. For i = 0 To nodes.Length - 1
  43. Set node = nodes.Item(i)
  44. If node.getAttribute("key") = key Then
  45. GetAppSetting = node.getAttribute("value")
  46. ' Cache the value for subsequent requests
  47. Application.Lock
  48. Application(cacheKey) = GetAppSetting
  49. Application.Unlock
  50. Exit Function
  51. End If
  52. Next
  53. GetAppSetting = "nothing"
  54. End Function
  55. Public Function GetEnvironmentValue(name)
  56. Dim shell, env, value
  57. value = ""
  58. On Error Resume Next
  59. Set shell = Server.CreateObject("WScript.Shell")
  60. Set env = shell.Environment("PROCESS")
  61. If Err.Number = 0 Then
  62. value = env(name)
  63. If Err.Number <> 0 Then
  64. Err.Clear
  65. value = ""
  66. End If
  67. Else
  68. Err.Clear
  69. End If
  70. On Error GoTo 0
  71. GetEnvironmentValue = Trim(CStr(value))
  72. End Function
  73. Public Function GetSecureSetting(key, envName)
  74. Dim value
  75. value = Trim(CStr(GetAppSetting(key)))
  76. If Len(value) > 0 And LCase(value) <> "nothing" Then
  77. GetSecureSetting = value
  78. Exit Function
  79. End If
  80. value = Trim(CStr(GetEnvironmentValue(envName)))
  81. If Len(value) > 0 Then
  82. GetSecureSetting = value
  83. Exit Function
  84. End If
  85. GetSecureSetting = ""
  86. End Function
  87. Public Sub ShowServerVariables
  88. Dim varName, htmlTable
  89. htmlTable = "<table border='1' cellspacing='0' cellpadding='5'>"
  90. htmlTable = htmlTable & "<thead><tr><th>Variable Name</th><th>Value</th></tr></thead><tbody>"
  91. ' Loop through all server variables
  92. For Each varName In Request.ServerVariables
  93. htmlTable = htmlTable & "<tr>"
  94. htmlTable = htmlTable & "<td>" & Server.HTMLEncode(varName) & "</td>"
  95. htmlTable = htmlTable & "<td>" & Server.HTMLEncode(Request.ServerVariables(varName)) & "</td>"
  96. htmlTable = htmlTable & "</tr>"
  97. Next
  98. htmlTable = htmlTable & "</tbody></table>"
  99. ' Output the HTML table
  100. Response.Write(htmlTable)
  101. End Sub
  102. '------------------------------------------------------------------------------
  103. ' Utility: IIf Function for VBScript
  104. ' Usage: result = IIf(condition, trueValue, falseValue)
  105. '------------------------------------------------------------------------------
  106. Function IIf(condition, trueValue, falseValue)
  107. On Error Resume Next
  108. If CBool(condition) Then
  109. IIf = trueValue
  110. Else
  111. IIf = falseValue
  112. End If
  113. If Err.Number <> 0 Then
  114. ' Optional: handle or log error in conversion/evaluation
  115. Err.Clear
  116. End If
  117. On Error GoTo 0
  118. End Function
  119. '-----------------------------
  120. ' Utility: Generic Error Reporter
  121. '-----------------------------
  122. Public Sub ErrorCheck(context)
  123. If Err.Number <> 0 Then
  124. Dim errHtml
  125. errHtml = "<div style='padding:10px; border:2px solid red; background:#fdd; font-family:Verdana; font-size:12px;'>"
  126. errHtml = errHtml & "<strong>Error occurred" & IIf(Not IsEmpty(context) And context <> "", ": " & context, "") & "</strong><br />"
  127. errHtml = errHtml & "<em>Time:</em> " & Now() & "<br />"
  128. errHtml = errHtml & "<em>Number:</em> " & Err.Number & "<br />"
  129. errHtml = errHtml & "<em>Description:</em> " & Server.HTMLEncode(Err.Description) & "<br />"
  130. If Len(Err.Source) > 0 Then
  131. errHtml = errHtml & "<em>Source:</em> " & Server.HTMLEncode(Err.Source) & "<br />"
  132. End If
  133. errHtml = errHtml & "</div>"
  134. Response.Write errHtml
  135. Err.Clear
  136. End If
  137. End Sub
  138. '------------------------------------------------------------------------------
  139. ' Utility: TrimQueryParams
  140. ' Removes everything from the first "?" or "&" onward.
  141. ' Usage:
  142. ' CleanPath = TrimQueryParams(rawPath)
  143. '------------------------------------------------------------------------------
  144. Function TrimQueryParams(rawPath)
  145. Dim posQ, posA, cutPos
  146. ' find the first occurrences of "?" and "&"
  147. posQ = InStr(rawPath, "?")
  148. posA = InStr(rawPath, "&")
  149. ' determine the earliest cut position (>0)
  150. If posQ > 0 And posA > 0 Then
  151. cutPos = IIf(posQ < posA, posQ, posA)
  152. ElseIf posQ > 0 Then
  153. cutPos = posQ
  154. ElseIf posA > 0 Then
  155. cutPos = posA
  156. Else
  157. cutPos = 0
  158. End If
  159. ' if found, return up to just before that char
  160. If cutPos > 0 Then
  161. TrimQueryParams = Left(rawPath, cutPos - 1)
  162. Else
  163. TrimQueryParams = rawPath
  164. End If
  165. End Function
  166. Sub Destroy(o)
  167. if isobject(o) then
  168. if not o is nothing then
  169. on error resume next
  170. o.close
  171. on error goto 0
  172. set o = nothing
  173. end if
  174. end if
  175. End Sub
  176. 'prepends indents
  177. Private Sub puti(v)
  178. put Spaces(m_indent) & v
  179. End Sub
  180. Sub put(v)
  181. Select Case typename(v)
  182. Case "LinkedList_Class" : response.write join(v.TO_Array, ", ")
  183. Case "DynamicArray_Class" : response.write JoinList(v)
  184. Case "Variant()" : response.write join(v, ", ")
  185. Case else : response.write v
  186. End Select
  187. End Sub
  188. Sub put_
  189. put "<br>"
  190. End Sub
  191. Sub putl(v)
  192. put v
  193. put_
  194. End Sub
  195. '---------------------------------------------------------------------------------------------------------------------
  196. 'Wrapper for Server.HTMLEncode() -- makes it easier on the eyes when reading the HTML code
  197. Function H(s)
  198. If Not IsEmpty(s) and Not IsNull(s) then
  199. H = Server.HTMLEncode(s)
  200. Else
  201. H = ""
  202. End If
  203. End Function
  204. '------------------------------------------------------------------------------
  205. ' Canonical application URL helpers
  206. ' - Categories use numeric IDs
  207. ' - Posts use slug permalinks for public links and numeric IDs for admin actions
  208. '------------------------------------------------------------------------------
  209. Function CategoryUrl(ByVal categoryId)
  210. CategoryUrl = "/categories/" & Server.URLEncode(CStr(categoryId))
  211. End Function
  212. Function CategoriesUrl()
  213. CategoriesUrl = "/categories"
  214. End Function
  215. Function CategoryNewUrl()
  216. CategoryNewUrl = "/categories/new"
  217. End Function
  218. Function CategoryEditUrl(ByVal categoryId)
  219. CategoryEditUrl = CategoryUrl(categoryId) & "/edit"
  220. End Function
  221. Function CategoryDeleteUrl(ByVal categoryId)
  222. CategoryDeleteUrl = CategoryUrl(categoryId) & "/delete"
  223. End Function
  224. Function PostUrl(ByVal slug)
  225. PostUrl = "/posts/" & Server.URLEncode(CStr(slug))
  226. End Function
  227. Function PostsUrl()
  228. PostsUrl = "/posts"
  229. End Function
  230. Function PostNewUrl()
  231. PostNewUrl = "/posts/new"
  232. End Function
  233. Function PostEditUrl(ByVal postId)
  234. PostEditUrl = "/posts/" & Server.URLEncode(CStr(postId)) & "/edit"
  235. End Function
  236. Function PostUpdateUrl(ByVal postId)
  237. PostUpdateUrl = "/posts/" & Server.URLEncode(CStr(postId))
  238. End Function
  239. Function PostDeleteUrl(ByVal postId)
  240. PostDeleteUrl = "/posts/" & Server.URLEncode(CStr(postId)) & "/delete"
  241. End Function
  242. Function AdminPostPublishUrl(ByVal postId)
  243. AdminPostPublishUrl = "/admin/posts/" & Server.URLEncode(CStr(postId)) & "/publish"
  244. End Function
  245. Function AdminPostUnpublishUrl(ByVal postId)
  246. AdminPostUnpublishUrl = "/admin/posts/" & Server.URLEncode(CStr(postId)) & "/unpublish"
  247. End Function
  248. Function AdminPostAIUrl(ByVal postId)
  249. AdminPostAIUrl = "/admin/posts/" & Server.URLEncode(CStr(postId)) & "/ai"
  250. End Function
  251. Function AdminUrl()
  252. AdminUrl = "/admin"
  253. End Function
  254. Function CommentsUrl()
  255. CommentsUrl = "/comments"
  256. End Function
  257. '=======================================================================================================================
  258. ' Adapted from Tolerable library
  259. '=======================================================================================================================
  260. ' This subroutine allows us to ignore the difference
  261. ' between object and primitive assignments. This is
  262. ' essential for many parts of the engine.
  263. Public Sub Assign(ByRef var, ByVal val)
  264. If IsObject(val) Then
  265. Set var = val
  266. Else
  267. var = val
  268. End If
  269. End Sub
  270. ' This is similar to the ? : operator of other languages.
  271. ' Unfortunately, both the if_true and if_false "branches"
  272. ' will be evalauted before the condition is even checked. So,
  273. ' you'll only want to use this for simple expressions.
  274. Public Function Choice(ByVal cond, ByVal if_true, ByVal if_false)
  275. If cond Then
  276. Assign Choice, if_true
  277. Else
  278. Assign Choice, if_false
  279. End If
  280. End Function
  281. ' Allows single-quotes to be used in place of double-quotes.
  282. ' Basically, this is a cheap trick that can make it easier
  283. ' to specify Lambdas.
  284. Public Function Q(ByVal input)
  285. Q = Replace(input, "'", """")
  286. End Function
  287. Function SurroundString(inputVar)
  288. If VarType(inputVar) = vbString Then
  289. SurroundString = """" & inputVar & """"
  290. Else
  291. SurroundString = inputVar
  292. End If
  293. End Function
  294. Function SurroundStringInArray(arr)
  295. Dim i
  296. For i = LBound(arr) To UBound(arr)
  297. If IsString(arr(i)) Then
  298. arr(i) = """" & arr(i) & """"
  299. End If
  300. Next
  301. SurroundStringInArray = arr
  302. End Function
  303. '-----------------------------------------------------------------------------------------------------------------------
  304. 'Boolean type checkers
  305. 'Don't forget IsArray is built-in!
  306. Function IsString(value)
  307. IsString = Choice(typename(value) = "String", true, false)
  308. End Function
  309. Function IsDict(value)
  310. IsDict = Choice(typename(value) = "Dictionary", true, false)
  311. End Function
  312. Function IsRecordset(value)
  313. IsRecordset = Choice(typename(value) = "Recordset", true, false)
  314. End Function
  315. Function IsLinkedList(value)
  316. IsLinkedList = Choice(typename(value) = "LinkedList_Class", true, false)
  317. End Function
  318. Function IsArray(value)
  319. IsArray = Choice(typename(value) = "Variant()", true, false)
  320. End Function
  321. '--------------------------------------------------------------------
  322. ' Returns True when the named key is present in Session.Contents
  323. ' • Handles scalars (String, Integer, etc.), objects, Empty, and Null
  324. '--------------------------------------------------------------------
  325. Function SessionHasKey(keyName)
  326. 'Loop over the existing keys—Session.Contents is like a dictionary
  327. Dim k
  328. For Each k In Session.Contents
  329. If StrComp(k, keyName, vbTextCompare) = 0 Then
  330. SessionHasKey = True
  331. Exit Function
  332. End If
  333. Next
  334. SessionHasKey = False 'not found
  335. End Function
  336. Function RenderObjectsAsTable(arr,boolUseTabulator)
  337. Dim html, propNames, i, j, obj, val, pkName, isPk
  338. If IsEmpty(arr) Or Not IsArray(arr) Then
  339. RenderObjectsAsTable = "<!-- no data -->"
  340. Exit Function
  341. End If
  342. Set obj = arr(0)
  343. On Error Resume Next
  344. propNames = obj.Properties
  345. pkName = obj.PrimaryKey
  346. On Error GoTo 0
  347. If IsEmpty(propNames) Or Len(pkName) = 0 Then
  348. RenderObjectsAsTable = "<!-- missing properties or primary key -->"
  349. Exit Function
  350. End If
  351. html = "<div class='table-wrapper'>" & vbCrLf
  352. html = html & "<table class='pobo-table' id='pobo-table'>" & vbCrLf
  353. html = html & " <thead><tr>" & vbCrLf
  354. For i = 0 To UBound(propNames)
  355. html = html & " <th>" & Server.HTMLEncode(propNames(i)) & "</th>" & vbCrLf
  356. Next
  357. html = html & " </tr></thead>" & vbCrLf
  358. html = html & " <tbody>" & vbCrLf
  359. For j = 0 To UBound(arr)
  360. Set obj = arr(j)
  361. html = html & " <tr>" & vbCrLf
  362. For i = 0 To UBound(propNames)
  363. val = GetDynamicProperty(obj, propNames(i))
  364. isPk = (StrComp(propNames(i), pkName, vbTextCompare) = 0)
  365. If IsNull(val) Or IsEmpty(val) Then
  366. val = "&nbsp;"
  367. ElseIf IsDate(val) Then
  368. val = FormatDateTime(val, vbShortDate)
  369. ElseIf VarType(val) = vbBoolean Then
  370. val = IIf(val, "True", "False")
  371. Else
  372. val = CStr(val)
  373. Dim maxLen : maxLen = CInt(GetAppSetting("TableCellMaxLength"))
  374. If maxLen <= 0 Then maxLen = 90
  375. If Len(val) > maxLen Then
  376. val = Left(val, maxLen - 3) & "..."
  377. End If
  378. val = Server.HTMLEncode(val)
  379. End If
  380. If isPk and boolUseTabulator = False Then
  381. val = "<a href=""" & obj.Tablename & "/edit/" & GetDynamicProperty(obj, pkName) & """ class=""table-link"">" & val & "</a>"
  382. End If
  383. html = html & " <td>" & val & "</td>" & vbCrLf
  384. Next
  385. html = html & " </tr>" & vbCrLf
  386. Next
  387. html = html & " </tbody>" & vbCrLf & "</table>" & vbCrLf & "</div>"
  388. RenderObjectsAsTable = html
  389. End Function
  390. Function RenderFormFromObject(obj)
  391. Dim html, propNames, i, name, val, inputType
  392. Dim pkName, tableName, checkedAttr
  393. On Error Resume Next
  394. propNames = obj.Properties
  395. pkName = obj.PrimaryKey
  396. tableName = obj.TableName
  397. On Error GoTo 0
  398. If IsEmpty(propNames) Or Len(pkName) = 0 Then
  399. RenderFormFromObject = "<!-- Invalid object -->"
  400. Exit Function
  401. End If
  402. html = "<form method='post' action='/" & tableName & "/save' class='article-content'>" & vbCrLf
  403. For i = 0 To UBound(propNames)
  404. name = propNames(i)
  405. val = GetDynamicProperty(obj, name)
  406. ' Handle nulls
  407. If IsNull(val) Then val = ""
  408. ' Primary key → hidden input
  409. If StrComp(name, pkName, vbTextCompare) = 0 Then
  410. html = html & " <input type='hidden' name='" & name & "' value='" & Server.HTMLEncode(val) & "' />" & vbCrLf
  411. 'Continue For
  412. End If
  413. html = html & " <div class='form-group'>" & vbCrLf
  414. html = html & " <label for='" & name & "'>" & name & "</label>" & vbCrLf
  415. Select Case True
  416. Case VarType(val) = vbBoolean
  417. checkedAttr = ""
  418. If val = True Then checkedAttr = " checked"
  419. html = html & " <input type='checkbox' class='form-check-input' name='" & name & "' id='" & name & "' value='true'" & checkedAttr & " />" & vbCrLf
  420. Case IsDate(val)
  421. html = html & " <input type='date' class='form-control' name='" & name & "' id='" & name & "' value='" & FormatDateForInput(val) & "' />" & vbCrLf
  422. Case IsNumeric(val)
  423. html = html & " <input type='number' class='form-control' name='" & name & "' id='" & name & "' value='" & val & "' />" & vbCrLf
  424. Case Len(val) > CInt(GetAppSetting("FormTextareaThreshold"))
  425. html = html & " <textarea class='form-control' name='" & name & "' id='" & name & "' rows='6'>" & Server.HTMLEncode(val) & "</textarea>" & vbCrLf
  426. Case Else
  427. html = html & " <input type='text' class='form-control' name='" & name & "' id='" & name & "' value='" & Server.HTMLEncode(val) & "' />" & vbCrLf
  428. End Select
  429. html = html & " </div>" & vbCrLf
  430. Next
  431. html = html & " <button type='submit' class='btn btn-primary btn-lg'>Save</button>" & vbCrLf
  432. html = html & "</form>" & vbCrLf
  433. RenderFormFromObject = html
  434. End Function
  435. Function GetDynamicProperty(obj, propName)
  436. On Error Resume Next
  437. Dim result
  438. Execute "result = obj." & propName
  439. If Err.Number <> 0 Then
  440. result = ""
  441. Err.Clear
  442. End If
  443. GetDynamicProperty = result
  444. On Error GoTo 0
  445. End Function
  446. Function FormatDateForInput(val)
  447. If IsDate(val) Then
  448. Dim yyyy, mm, dd
  449. yyyy = Year(val)
  450. mm = Right("0" & Month(val), 2)
  451. dd = Right("0" & Day(val), 2)
  452. FormatDateForInput = yyyy & "-" & mm & "-" & dd
  453. Else
  454. FormatDateForInput = ""
  455. End If
  456. End Function
  457. '-------------------------------------------------------------
  458. ' Returns obj.<propName> for any public VBScript class property
  459. '-------------------------------------------------------------
  460. Function GetObjProp(o, pName)
  461. Dim tmp
  462. ' Build a tiny statement like: tmp = o.UserID
  463. Execute "tmp = o." & pName
  464. GetObjProp = tmp
  465. End Function
  466. Function GenerateSlug(title)
  467. Dim slug
  468. slug = LCase(title) ' Convert to lowercase
  469. slug = Replace(slug, "&", "and") ' Replace ampersands
  470. slug = Replace(slug, "'", "") ' Remove apostrophes
  471. slug = Replace(slug, """", "") ' Remove quotes
  472. slug = Replace(slug, "–", "-") ' Replace en dash
  473. slug = Replace(slug, "—", "-") ' Replace em dash
  474. slug = Replace(slug, "/", "-") ' Replace slashes
  475. slug = Replace(slug, "\", "-") ' Replace backslashes
  476. ' Remove all non-alphanumeric and non-hyphen/space characters
  477. Dim i, ch, clean
  478. clean = ""
  479. For i = 1 To Len(slug)
  480. ch = Mid(slug, i, 1)
  481. If (ch >= "a" And ch <= "z") Or (ch >= "0" And ch <= "9") Or ch = " " Or ch = "-" Then
  482. clean = clean & ch
  483. End If
  484. Next
  485. ' Replace multiple spaces or hyphens with single hyphen
  486. Do While InStr(clean, " ") > 0
  487. clean = Replace(clean, " ", " ")
  488. Loop
  489. clean = Replace(clean, " ", "-")
  490. Do While InStr(clean, "--") > 0
  491. clean = Replace(clean, "--", "-")
  492. Loop
  493. ' Trim leading/trailing hyphens
  494. Do While Left(clean, 1) = "-"
  495. clean = Mid(clean, 2)
  496. Loop
  497. Do While Right(clean, 1) = "-"
  498. clean = Left(clean, Len(clean) - 1)
  499. Loop
  500. GenerateSlug = clean
  501. End Function
  502. Function GetRawJsonFromRequest()
  503. Dim stream, rawJson
  504. Set stream = Server.CreateObject("ADODB.Stream")
  505. stream.Type = 1 ' adTypeBinary
  506. stream.Open
  507. stream.Write Request.BinaryRead(Request.TotalBytes)
  508. stream.Position = 0
  509. stream.Type = 2 ' adTypeText
  510. stream.Charset = "utf-8"
  511. rawJson = stream.ReadText
  512. stream.Close
  513. Set stream = Nothing
  514. GetRawJsonFromRequest = rawJson
  515. End Function
  516. Function Active(controllerName)
  517. On Error Resume Next
  518. If Replace(Lcase(router.Resolve(Request.ServerVariables("REQUEST_METHOD"), TrimQueryParams(Request.ServerVariables("HTTP_X_ORIGINAL_URL")))(0)),"controller","") = LCase(controllerName) Then
  519. Active = "active"
  520. Else
  521. Active = ""
  522. End If
  523. On Error GoTo 0
  524. End Function
  525. '====================================================================
  526. ' FormatDateForSql
  527. ' Converts a VBScript Date to a SQL Server-compatible string
  528. ' Output: 'YYYY-MM-DD HH:MM:SS'
  529. '====================================================================
  530. Function FormatDateForSql(vbDate)
  531. If IsNull(vbDate) Or vbDate = "" Then
  532. FormatDateForSql = "NULL"
  533. Exit Function
  534. End If
  535. ' Ensure vbDate is a valid date
  536. If Not IsDate(vbDate) Then
  537. Err.Raise vbObjectError + 1000, "FormatDateForSql", "Invalid date: " & vbDate
  538. End If
  539. Dim yyyy, mm, dd, hh, nn, ss
  540. yyyy = Year(vbDate)
  541. mm = Right("0" & Month(vbDate), 2)
  542. dd = Right("0" & Day(vbDate), 2)
  543. hh = Right("0" & Hour(vbDate), 2)
  544. nn = Right("0" & Minute(vbDate), 2)
  545. ss = Right("0" & Second(vbDate), 2)
  546. ' Construct SQL Server datetime literal
  547. FormatDateForSql = "'" & yyyy & "-" & mm & "-" & dd & " " & hh & ":" & nn & ":" & ss & "'"
  548. End Function
  549. %>

Powered by TurnKey Linux.